Обновление Redux Store из изменений в дочерних компонентах - PullRequest
1 голос
/ 20 июня 2020

Я новичок в React и изучаю Redux. У меня есть компонент-контейнер с двумя дочерними компонентами. В одном из дочерних компонентов (компонент заголовка) у меня есть пять кнопок. Его родственный компонент (компонент Body) отображает разные представления в зависимости от кнопки, нажатой в компоненте Header. Я знаю, что могу добиться этого, сохраняя состояние в родительском компоненте и имея функцию обработчика событий, которая получает функцию обратного вызова при нажатии кнопки, но я пытаюсь изучить Redux для более сложных приложений.

Чтобы реализовать это, я представил функцию-обработчик в родительском компоненте, которая отправляет действие из данных, полученных от функции обратного вызова, переданной компоненту Header, чтобы изменить хранилище и, следовательно, отобразить соответствующее представление из компонента Body.

Вот пример кода:

Родительский компонент:

...
const mapStateToProps = state => {
  return {
    selectedDS: state.selectedDS
  };
};

const mapDispatchToProps = dispatch => ({
  changeDs: selectedDS => dispatch(changeDs(selectedDS)),
  dispatch
});

class Main extends Component {
  handleClick = button => {
    this.props.dispatch(changeDs(button));
  };

  render() {
    return (
      <>
        <div className="container">
          <div id="header" className="row">
            <Header handleClick={this.handleClick} />
          </div>
          <div className="row">
            <DsComponent ds={this.props} />
          </div>
        </div>
      </>
    );
  }
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Main);

Компонент заголовка:

...
export default function Header(props) {
  return (
    <>
      <div className="mx-auto">
        <Navbar>
          <Nav>
            <NavItem>
              <Button className="number" onClick={() => props.handleClick(0)}>
                Number
              </Button>
            </NavItem>
            <NavItem>
              <Button className="array" onClick={() => props.handleClick(1)}>
                Array
              </Button>
            </NavItem>
            <NavItem>
              <Button className="string" onClick={() => props.handleClick(2)}>
                String
              </Button>
            </NavItem>
            <NavItem>
              <Button className="tree" onClick={() => props.handleClick(3)}>
                Tree
              </Button>
            </NavItem>
            <NavItem>
              <Button className="graph" onClick={() => props.handleClick(4)}>
                Graph
              </Button>
            </NavItem>
          </Nav>
        </Navbar>
      </div>
    </>
  );
}

Извините за длину код, вот ссылка на песочницу

Мой вопрос:

  • Что не так в коде?

  • Каков наилучший метод отправки действий глубже в дереве компонентов, если я хочу, чтобы компоненты были простыми?

1 Ответ

0 голосов
/ 20 июня 2020

ПРОБЛЕМА:

с вашим reducer, вы устанавливали значение магазина неправильно, вы устанавливаете значение магазина

var payload_ds = action.payload;
return Object.assign({}, state, { payload_ds });

// above line create json object something like this
// { selectedDS: 0 , payload_ds: { selectedDS: 4 } }

РЕШЕНИЕ:

var payload_ds = action.payload.selectedDS;
return Object.assign({}, state, { selectedDS: payload_ds }); // <----- HERE

// OR

// as there is only one field you can also use this one
return { selectedDS: payload_ds }

РАБОЧАЯ ДЕМО:

Отредактируйте awesome-mirzakhani-oc11h

Q: Каков наилучший метод отправки действий глубже в дереве компонентов, если я хочу, чтобы компоненты были простыми компонентами?

A: Вы можете использовать mapDispatchToProps, поскольку вы передаете все как свойства, это все еще рассматривается как тупой компонент.

...