1

我尝试使用带有钩子的反应。我有这个状态:

const [state, setState] = useState<State>({
    titel: "",
    somethingElse: "",
    tabledata: [],
});

我有两个使用效果:

// componentDidMount, Initial variable deklaration
useEffect(() => {
    //Do something

    //Set initial states
    setState({
        ...state,
        titel: props.titel,
        somethingElse: props.somethingElse,
    })

}, []);

// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {

    //Do something and generate tabledata
    let tabledata ....

    //Set tabledata
    setState({
        ...state,
        tabledata: tabledata,
    })

}, [props.taenzer]);

现在我有了这样的行为,即第二个 useEffect 覆盖了第一个 useEffect setState 命令。我的变量 title 和 somethingElse 始终为空。

现在我可以通过以下方式更改我的状态声明:

const [titel, setTitel] = useState<>({
    titel = ""
});
const [somethingElse, setSomethingElse] = useState<>({
    somethingElse = ""
});

但这使得整体变得不清楚,并且像 setState(...state, title="Hello", somethingElse="Else") 那样一次性设置多个变量的状态并不容易

还有其他可能吗?

4

1 回答 1

3

第二个 useEffect 覆盖第一个 useEffect setState

useState函数不会自动合并状态。因此,您需要利用可通过回调访问的先前状态。

useEffect(
  () => {
    const tabledata = ...
    setState(prevState => ({ // use previous state
      ...prevState,
      tabledata
    }))
  }, [props.taenzer]
)

还有其他可能吗?

您可以通过延迟初始化您的状态props并删除第一个效果(不依赖)

const [{ title, somethingElse, tabledata }, setState] = useState<State>({
    ...props,
    tabledata: [],
});
于 2019-10-03T08:52:53.490 回答