Обновление состояния от дочернего компонента к родительскому компоненту

#javascript #reactjs

#javascript #reactjs

Вопрос:

Я борюсь с проблемой App.js который имеет компонент с флажками. Когда кто-то устанавливает флажок в этом компоненте, я хочу, чтобы состояние для этого флажка обновлялось в App.js досье. Код для моего компонента Checkboxes приведен ниже. Я использую material ui, если это имеет какое-либо значение.

 import Checkbox from '@material-ui/core/Checkbox';
import FormGroup from '@material-ui/core/FormGroup';
import FormControlLabel from '@material-ui/core/FormControlLabel';

export default function CheckboxLabels() {
  return (
    <FormGroup row>
      <FormControlLabel
        control={<Checkbox name="checkedD" />}
        label="Remove Duplicates"
      />
    </FormGroup>
  );
}
 

Код в App.js то, что имеет отношение к делу, это:

 <Grid>
  <Checkboxes  />
</Grid>
 

Что я должен делать? Как мне изменить приведенный выше код?

Ответ №1:

Если вы хотите сохранить состояние в App компоненте, вам необходимо передать функцию вашему дочернему компоненту, которая будет использоваться для отправки состояния родительскому App компоненту () .

В вашем родительском компоненте вы должны создать состояние, чтобы можно было сохранить каждое состояние флажков, и передать функцию, которая будет обрабатывать обновление состояния. Я бы сохранил состояние, Map чтобы избежать дублирования одного и того же флажка при каждом обновлении. Кроме того, передайте id каждому из компонентов флажка, чтобы вы знали, какое состояние ссылается на какой флажок при последующем обновлении.

 import React from "react";
import CheckboxLabels from "./CheckboxLabel";

class App extends React.Component {
  state = {
    checkboxes: new Map()
  };

  handleClick = (e, id) => {
    const { checked } = e.target;

    this.setState((prevState) => ({
      checkboxes: prevState.checkboxes.set(id, checked)
    }));
  };

  render() {
    return (
      <div className="App">
        <CheckboxLabels id={1} handleClick={this.handleClick} />
        <CheckboxLabels id={2} handleClick={this.handleClick} />
        <CheckboxLabels id={3} handleClick={this.handleClick} />
        <CheckboxLabels id={4} handleClick={this.handleClick} />
      </div>
    );
  }
}

export default App;

 

В вашем дочернем компоненте вы должны принять функцию и id , а затем передать эту функцию с event id onChange помощью метода and in флажка.

 import React from "react";
import Checkbox from "@material-ui/core/Checkbox";
import FormGroup from "@material-ui/core/FormGroup";
import FormControlLabel from "@material-ui/core/FormControlLabel";

export default function CheckboxLabels({ id, handleClick }) {
  return (
    <FormGroup row>
      <FormControlLabel
        control={<Checkbox name="checkedD" />}
        label="Remove Duplicates"
        onChange={(e) => handleClick(e, id)}
      />
    </FormGroup>
  );
}
 

Таким образом, вы можете сохранить состояние нескольких флажков, и вы можете легко отслеживать, какое состояние какое с помощью id .

Комментарии:

1. Я не понимаю перехваты — я использую компонент класса. Кроме того, после просмотра предоставленного примера кода может оказаться уместным, что в моем реальном приложении у меня будет около 10 различных флажков, состояние каждого из которых я хочу отслеживать. Будет ли это иметь значение? Я совсем новичок в React и программировании снова. Я потратил часы на это одно и то же, но ничего не добился. 🙁

2. Можете ли вы поделиться своим кодом через codesandbox и вставить ссылку сюда? Вам будет легче помочь, посмотрев на точный код, который у вас есть. Затем я смогу показать вам и объяснить, как это сделать с помощью компонентов класса, а также как сохранить состояние каждого флажка

3. @Jon Я обновил свой первоначальный ответ, используя компоненты класса и сохраняя состояние нескольких флажков. Пожалуйста, дайте мне знать, если это поможет.

4. Спасибо за это. Я немного новичок в stackoverflow и очень новичок в codesandbox! Вот ссылка, чтобы вы могли видеть, над чем я работаю, и причины, по которым мне нужно, чтобы этот флажок работал: codesandbox.io/s/elated-dust-tcle7?file=/src/index.js

5. @Jon Я отредактировал ваш код и добавил функцию, которая обрабатывает все флажки и сохраняет их в соответствующем состоянии. Что вы можете сделать сейчас, так это вызвать соответствующие функции для обновления текста в инструкции switch, которую я написал, или, используя логические значения состояния этих флажков, записать логику в componentDidUpdate() . codesandbox.io/s/crimson-sky-zmd3n?file=/src/components/App.js

Ответ №2:

Вы можете использовать обычный механизм состояния в родительском и просто передать его CheckboxLabels компоненту. Так что отправляйте setChecked и checked значения вниз:

 export default function CheckboxLabels({ checked, onChange }) {
  return (
    <FormGroup row>
      <FormControlLabel
        control={
          <Checkbox
            name="checkedD"
            checked={checked}
            onChange={(e) => {
              if (onChange) {
                onChange(e.target.checked);
              }
            }}
          />
        }
        label="Remove Duplicates"
      />
    </FormGroup>
  );
}
 
 export default function App() {
  const [checked, setChecked] = useState(false);
  return (
    <Grid>
      <CheckboxLabels checked={checked} onChange={setChecked} />
    </Grid>
  );
}
 

Я не уверен, что ваш код хорош с точки зрения именования, но я добавил, что компонент флажка — это имя CheckboxLabels