为什么在下面的伪代码示例中,当容器更改foo.bar时,子不重新呈现?

Container {
  handleEvent() {
    this.props.foo.bar = 123
  },

  render() {
    return <Child bar={this.props.foo.bar} />
}

Child {
  render() {
    return <div>{this.props.bar}</div>
  }
}

即使我在修改Container中的值后调用forceUpdate(), Child仍然显示旧值。


当前回答

export default function DataTable({ col, row }) {
  const [datatable, setDatatable] = React.useState({});
  useEffect(() => {
    setDatatable({
      columns: col,
      rows: row,
    });
  /// do any thing else 
  }, [row]);

  return (
    <MDBDataTableV5
      hover
      entriesOptions={[5, 20, 25]}
      entries={5}
      pagesAmount={4}
      data={datatable}
    />
  );
}

这个例子使用useEffect在道具改变时改变状态。

其他回答

当从函数和useState创建React组件时。

const [drawerState, setDrawerState] = useState(false);

const toggleDrawer = () => {
      // attempting to trigger re-render
      setDrawerState(!drawerState);
};

这行不通

         <Drawer
            drawerState={drawerState}
            toggleDrawer={toggleDrawer}
         />

这是可行的(添加键)

         <Drawer
            drawerState={drawerState}
            key={drawerState}
            toggleDrawer={toggleDrawer}
         />

我也遇到了同样的问题。 我有一个Tooltip组件,它正在接收showTooltip道具,我正在基于if条件在父组件上更新,它正在父组件中更新,但Tooltip组件没有呈现。

const Parent = () => {
   let showTooltip = false;
   if(....){ showTooltip = true; }
   return(
      <Tooltip showTooltip={showTooltip}></Tooltip>
   )
}

我犯的错误是将showTooltip声明为let。

我意识到我做错了什么,我违反了渲染工作的原则,用钩子代替它。

const [showTooltip, setShowTooltip] =  React.useState<boolean>(false);

根据React的理念,组件不能改变它的道具。它们应该从父进程接收,并且应该是不可变的。只有父节点可以更改其子节点的道具。

关于国家和道具的解释很好

另外,阅读这篇文章为什么我不能在react.js中更新道具?

考虑到道具的渲染限制和状态的增益,如果你使用反应钩子,你可以使用一些技巧。例如,您可以使用useEffect手动将道具转换为状态。这可能不是最好的做法,但在这些情况下是有帮助的。

import { isEqual } from 'lodash';
import { useEffect, useState } from 'react';

export const MyComponent = (props: { users: [] }) => {
  const [usersState, setUsersState] = useState([]);

  useEffect(() => {
    if (!isEqual(props.users, usersState)) {
      setUsersState(props.users);
    }
  }, [props.users]);

  <OtherComponent users={usersState} />;
};

我也有同样的问题。 这是我的解决方案,我不确定这是一个好的实践,如果不是告诉我:

state = {
  value: this.props.value
};

componentDidUpdate(prevProps) {
  if(prevProps.value !== this.props.value) {
    this.setState({value: this.props.value});
  }
}

UPD:现在你可以用React Hooks做同样的事情: (仅当component是函数时)

const [value, setValue] = useState(propName);
// This will launch only if propName value has chaged.
useEffect(() => { setValue(propName) }, [propName]);