【问题标题】:How to sync state in react.js?如何在 react.js 中同步状态?
【发布时间】:2021-06-08 03:13:36
【问题描述】:

我在更新我的状态和我的组件时遇到了困难。按下按钮后,我更改了弹出组件的其中一个道具的值。道具的价值不会更新。我相信这是使用 setstate 的副作用之一。我做了一些研究,发现有一种方法可以使用 useeffect 钩子解决这个问题,但我无法收到结果。下面是我的代码:

我的目标是从具有 Data0 道具的表单获得 Data1 道具,但道具似乎根本没有更新。 我正在模拟单击多个对象,结果是 fromData 值的更新。因此,app.js 是我的父组件。子组件是弹出窗口,其值应更改为 Bob 和实际日期,而不仅仅是原始名称和原始日期的字符串值。

import React, { useState, useEffect } from 'react';
import './App.css';
import FormDialog from './component/popup'
import Button from '@material-ui/core/Button';


function App() {
  const Data0 = { name:'original name', date:'original date' }
  const Data1 = { name:'Bob', date:'1939' }
  const [formStatus, setformStatus] = React.useState(false);
  const [formdata2, setformData2] = useState(Data0)
  const [tempform, settempform] = useState(<FormDialog formStatus = {formStatus} handelForm={() => handelForm()} Data0={Data0}/>)


  const handelForm = () => {
    const tempform = <FormDialog formStatus = {formStatus} handelForm={() => handelForm()} Data0={Data1}/>
    settempform(tempform);
  };

  useEffect(() => {
    const tempform = <FormDialog formStatus = {formStatus} handelForm={() => handelForm()} Data0={Data1}/>
    settempform(tempform);
    setformStatus(!formStatus);
    console.log('formdata2 EFFECT', formdata2)
    settempform(tempform);
    setformStatus(!formStatus);
    setformStatus(!formStatus);
  }, [formdata2]
  );

  return (
    <div className="App">
      <h1 align="center">React-App</h1>
      <h4 align='center'>Render Custom Component in Material Table</h4>
      <Button variant="outlined" color="primary" onClick={() => handelForm()}>
        Vendor row
      </Button>
      {tempform}
      {formdata2.billingVendor}
    </div>
  );
}

export default App;
export default function FormDialog (props) {
  let [Data, setData] = React.useState(props.Data0);

  return (
    <React.Fragment>
      <Dialog
        maxWidth='lg'
        open={props.formStatus}
        aria-labelledby="max-width-dialog-title"
        disableBackdropClick= {true}
        disableEscapeKeyDown={true}
      >
        <DialogTitle className={classes.title}>{Data.name}</DialogTitle>
        <Divider />
        <DialogContent>
            <DialogContentText>
                Please be cautious when updating the fields below.
            </DialogContentText>
            <form noValidate>
                <FormControl className={classes.formControl} fullWidth= {true}>
                <div className={classes.root}>
                    <TextField
                        fullWidth
                        label='Date'
                        style={{ margin: 8 }}
                        disabled
                        value={Data.name}
                        variant="outlined"
                        />
                    <br/>
                    <TextField
                        fullWidth
                        label='Date'
                        style={{ margin: 8 }}
                        disabled
                        value={Data.name}
                        variant="outlined"
                        />
                    <br/>
                    <TextField
                        fullWidth
                        style={{ margin: 8 }}
                        disabled
                        value={Data.date}
                        variant="outlined"
                        />
                    <br/>
                    <TextField
                        fullWidth
                        style={{ margin: 8 }}
                        disabled
                        value={Data.date}
                        variant="outlined"
                        />
                    <br/>
                    
                    </div>

                </FormControl>
            </form>
        </DialogContent>
        <DialogActions>
          <Button onClick={() => props.handelForm()} color="primary">
            Close
          </Button>
        </DialogActions>
      </Dialog>
    </React.Fragment>
  );
}```

【问题讨论】:

  • 您正在根据子组件中的 props 值创建一个新状态,该状态与父组件中的状态独立。因此,子项的更改无法传递回父项。

标签: javascript reactjs react-hooks material-ui


【解决方案1】:

我认为您遵循的过程不是一个好的过程。您不应该在 state 中存储 react 组件,而应该动态加载组件或传递您需要的 prop。

import React, { useState, useEffect } from 'react';
import './App.css';
import FormDialog from './component/popup'
import Button from '@material-ui/core/Button';


function App() {
  const Data0 = { name:'original name', date:'original date' }
  const Data1 = { name:'Bob', date:'1939' }
  const [formStatus, setformStatus] = React.useState(false);
  const [formdata2, setformData2] = useState(Data0)
  const [formData, setFormData] = useState(Data0)


  const handelForm = () => {
    // here change the state however you want

    setFormData(Data0);
  };

  return (
    <div className="App">
      <h1 align="center">React-App</h1>
      <h4 align='center'>Render Custom Component in Material Table</h4>
      <Button variant="outlined" color="primary" onClick={() => handelForm()}>
        Vendor row
      </Button>
       <FormDialog formStatus = {formStatus} handelForm={() => handelForm()} Data0={formData}/>
    </div>
  );
}

export default App;

FormDialog中添加useEffect来执行更改

useEffect(() => {
    setData(props.Data0)
}, [props.Data0])

这是通过更改更新状态

【讨论】:

  • 这不会导致传递到 FormDialog 的道具被更新。请尝试运行上面的代码。谢谢!
  • 因为我没有通过更新的道具。您必须在 handelForm 中随心所欲地更新值
  • 我添加了行 setFormData(Data1); setformStatus(true);
  • 在弹出窗口中,显示的值仍然是原始值
  • 我已经更新了解决方案。我们必须寻找 FormDialog 的变化并使用 useEffect 更新状态
【解决方案2】:

您正在根据子组件中道具的值创建一个新状态,该状态独立于父组件中的状态。因此,子项的更改无法传递回父项。

修复它,

  1. 在父组件中创建状态
const [Data0, setData0] = useState({ name:'original name', date:'original date' })
  1. 通过setState 函数将父组件中的值更改为您的子组件
const tempform = <FormDialog formStatus = {formStatus} handelForm={() => handelForm()} Data={Data1} setData={setData0}/>
  1. 相应地更改子组件中的值
let {Data, setData} = props;

那么setData的调用应该是调用你父组件中的那个,它应该能够相应地更新值。

【讨论】:

  • 我知道你来自哪里。我应该更清楚的是,我正在模拟单击多个对象,结果是 fromData 值的更新。因此,app.js 是我的父组件。子组件是弹出窗口,其值应更改为 Bob 和实际日期,而不仅仅是原始名称和原始日期的字符串值。
猜你喜欢
  • 2014-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-11
相关资源
最近更新 更多