使用挂钩将状态从子级传递到父级-React

时间:2020-10-08 22:00:18

标签: reactjs

基本上,我想将“文件名”状态从 child 组件传递给 parent 组件。这样,我就可以在父项的onSubmit函数中使用“文件名”状态。我该如何实现?当前未定义父级的文件名。非常感谢您的帮助。

父母:

const AddLocation = ({ addLocation }) => {
  const initialFormState = { title: '', thumbnail: '' };
  const [location, setLocation] = useState(initialFormState);

  const onChange = (e) => {
    setLocation({ ...location, [e.target.name]: e.target.value });
  };

  const onSubmit = () => {
    addLocation({
      ...location,
      thumbnail: filename // I want to use filename state from child here.
    });
  };

  return (
        <form onSubmit={onSubmit}>
          <TextInput
            id="add-loc-title"
            name="title"
            value={location.title}
            onChange={onChange}
          />
          <FileUpload />
          <Button type="submit">Submit</Button>
        </form>
  );
};

孩子:

const FileUpload = () => {
  const [file, setFile] = useState('');
  const [filename, setFilename] = useState('Choose File');

  const onChange = (e) => {
    setFile(e.target.files[0]);
    setFilename(e.target.files[0].name);
  };

  const onSubmit = async () => {
    const formData = new FormData();
    formData.append('file', file);
    await axios.post('/upload', formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    });
  };

  return (
      <form onSubmit={onSubmit}>
        <TextInput
          id="add-cat-thumb"
          name="thumbnail"
          type="file"
          onChange={onChange}
      </form>
    </>
  );
};

2 个答案:

答案 0 :(得分:1)

您应该在父级处理一个状态,并将setState传递给子级。然后在事件上调用它。

父母:

  const [file, setFile] = useState(''); // create a state as the parent

  const onSubmit = () => {
    addItem({
      ...item,
      file: filename
    });
  };
    
  return <FileUpload parentSetFile={setFile}/>

然后在孩子中使用parentSetFile

  const onChange = (e) => {
    props.parentSetFile(e.target.files[0]) // For Example
    setFile(e.target.files[0]);
    setFilename(e.target.files[0].name);
  };

发布完整代码后进行编辑:

所以我假设您希望提交成功后在父文件中更新文件,然后您应该执行以下操作:

父母:

const AddLocation = ({ addLocation }) => {
  const initialFormState = { title: '', thumbnail: '' };
  const [location, setLocation] = useState(initialFormState);
  const [submittedFileName, setSubmittedFileName] = useState(null); // New state here to save the submitted file from child.

  const onChange = (e) => {
    setLocation({ ...location, [e.target.name]: e.target.value });
  };

  const onSubmit = () => {
    addLocation({
      ...location,
      thumbnail: submittedFileName  // Use the submitted file name - a state handled in this component (Parent)
    });
  };

  return (
        <form onSubmit={onSubmit}>
          <TextInput
            id="add-loc-title"
            name="title"
            value={location.title}
            onChange={onChange}
          />
          <FileUpload updateFileNameToParent={setSubmittedFileName} /> // Pass teh function that sets submittedFileName to the child so he could use it anyware he wants (probably after submit).
          <Button type="submit">Submit</Button>
        </form>
  );
};

孩子:

const FileUpload = (props) => {  // Since this component now gets props, we should pass it here
  const [file, setFile] = useState('');
  const [filename, setFilename] = useState('Choose File');

  const onChange = (e) => {
    setFile(e.target.files[0]);
    setFilename(e.target.files[0].name);
  };

  const onSubmit = async () => {
    const formData = new FormData();
    formData.append('file', file);
    await axios.post('/upload', formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    });
    props.updateFileNameToParent(filename) // Call the function that sets submitedFileName for parent with the filename in the state of this component (Child)
  };

  return (
      <form onSubmit={onSubmit}>
        <TextInput
          id="add-cat-thumb"
          name="thumbnail"
          type="file"
          onChange={onChange}
      </form>
    </>
  );
};

答案 1 :(得分:1)

基本思想是这样的:假设您有一个名为的带有状态变量fileName的react组件。假设您需要从Parent的render函数运行另一个名为的react组件。然后,要在TheChild中使用父级的方法,函数,状态变量等,您可以将父级的引用传递给子级,如下所示:

   return( 
              ...
             <TheChild calledMe={this} />
              ...
   )

这将允许您使用TheChild的代码中的this.props。namedMe来更新Parent组件的状态,如下所示:

this.props.calledMe.setState({fileName: .......}, () => {maybe do something else with fileName state variable})