反应:为什么道具改变时子组件不更新

2020/11/15 17:22 · javascript ·  · 0评论

为什么在以下伪代码示例中,当Container更改foo.bar时,Child不会重新渲染?

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

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

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

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

更新子项以使其属性“键”等于名称。每次更改键时,组件都会重新渲染。

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

因为如果父项的props发生变化,但是STATE的状态发生变化,则子项不会重新呈现:

您显示的是这样的:https :
//facebook.github.io/react/tips/communicate-between-components.html

它将通过道具将数据从父级传递到子级,但是那里没有重新渲染逻辑。

您需要为父级设置一些状态,然后在父级更改状态下重新渲染子级。这可能会有所帮助。
https://facebook.github.io/react/tips/expose-component-functions.html

我有同样的问题。这是我的解决方案,我不确定这是否是个好习惯,如果不是,请告诉我:

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]);

根据React哲学的组成部分,无法更改其道具。它们应该从父母那里收到,并且应该是不变的。只有父母可以改变孩子的道具。

关于状态与道具的很好的解释

另外,请阅读此线程为什么我不能在react.js中更新道具?

确认后,添加密钥即可。我浏览了文档以尝试并了解原因。

在创建子组件时,React希望高效。如果它与另一个子组件相同,则不会渲染新组件,这会使页面加载更快。

添加一个键会强制React渲染一个新组件,从而为该新组件重置State。

https://reactjs.org/docs/reconciliation.html#recursing-on-children

functions创建React组件时useState

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}
         />

您应该使用setState功能。否则,无论您如何使用forceUpdate,state都不会保存您的更改。

Container {
    handleEvent= () => { // use arrow function
        //this.props.foo.bar = 123
        //You should use setState to set value like this:
        this.setState({foo: {bar: 123}});
    };

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

您的代码似乎无效。我无法测试此代码。

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在更改时props更改状态

使用setState函数。所以你可以做

       this.setState({this.state.foo.bar:123}) 

在handle事件方法中。

状态一旦更新,将触发更改,然后进行重新渲染。

如果不保持任何状态而只是渲染道具然后从父级调用它,则应该将Child用作功能组件。替代方法是,可以将钩子与功能组件(useState)一起使用,这将导致无状态组件重新呈现。

同样,您不应该更改道具,因为它们是不可变的。维护组件的状态。

Child = ({bar}) => (bar);

我遇到了同样的问题。我有一个Tooltip正在接收showTooltip道具组件,我正在Parent根据if条件组件上进行更新,它正在组件中进行更新,ParentTooltip组件未渲染。

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

我正在做的错误是声明showTooltip为let。

我意识到自己做错了我违反了渲染工作原理的工作,用钩子代替了工作。

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

在子组件的connect方法的mapStateToProps中定义更改的道具。

function mapStateToProps(state) {
  return {
    chanelList: state.messaging.chanelList,
  };
}

export default connect(mapStateToProps)(ChannelItem);

就我而言,channelList的频道已更新,因此我在mapStateToProps中添加了chanelList

本文地址:http://javascript.askforanswer.com/fanyingweishenmedaojugaibianshizizujianbugengxin.html
文章标签: ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!