Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/90.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 反应:为什么子组件不';道具更改时不更新_Javascript_Html_Reactjs - Fatal编程技术网

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

Javascript 反应:为什么子组件不';道具更改时不更新,javascript,html,reactjs,Javascript,Html,Reactjs,为什么在下面的伪代码示例中,当容器更改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> } } 容

为什么在下面的伪代码示例中,当容器更改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>
  }
}
容器{
handleEvent(){
this.props.foo.bar=123
},
render(){
返回
}
孩子{
render(){
返回{this.props.bar}
}
}

即使我在修改容器中的值后调用
forceUpdate()
,子对象仍会显示旧值。

因为如果父对象的属性更改,但其状态更改,子对象不会重新渲染:)

您展示的是:

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

您需要为父级设置一些状态,然后在父级更改状态时重新渲染子级。 这可能会有所帮助。

您应该使用
设置状态
功能。否则,状态将不会保存您的更改,无论您如何使用forceUpdate

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>
        }
    }
}
容器{
handleEvent=()=>{//使用箭头函数
//this.props.foo.bar=123
//您应该使用setState设置如下值:
this.setState({foo:{bar:123});
};
render(){
返回
}
孩子{
render(){
返回{this.props.bar}
}
}
}

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

根据React哲学,组件无法更改其道具。它们应该从父级接收,并且应该是不可变的。只有父级可以更改其子级的道具

很好的解释

另外,阅读此线程,并使用setState函数。 所以你可以

       this.setState({this.state.foo.bar:123}) 
在handle事件方法内部


更新状态后,它将触发更改,并将进行重新渲染。

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

Child {
  render() {
    return <div key={this.props.bar}>{this.props.bar}</div>
  }
}
Child{
render(){
返回{this.props.bar}
}
}
我也有同样的问题。 这是我的解决方案,我不确定这是否是好的做法,如果不是,请告诉我:

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

componentDidUpdate(prevProps) {
  if(prevProps.value !== this.props.value) {
    this.setState({value: this.props.value});
  }
}
UPD:现在,您可以使用React挂钩执行相同的操作: (仅当组件是函数时)


如果子组件不维护任何状态,只需呈现道具,然后从父组件调用它,那么您可能应该将其作为功能组件。另一种选择是,您可以将挂钩与功能组件(useState)一起使用,这将导致无状态组件重新呈现

此外,您不应该更改PROPA,因为它们是不可变的。请维护组件的状态

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

确认了,添加了一个关键点。我浏览了文档,试图了解原因

React希望在创建子组件时效率更高。如果新组件与另一个子组件相同,它将不会呈现新组件,这会加快页面加载速度

添加关键点将对渲染新组件作出反应,从而重置该新组件的状态

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

export default connect(mapStateToProps)(ChannelItem);

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

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

函数
使用状态
创建反应组件时

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

const toggleDrawer = () => {
      // attempting to trigger re-render
      setDrawerState(!drawerState);
};
这不起作用

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

不起作用(添加键)


在子组件的连接方法的MapStateTrops中定义更改的道具

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

export default connect(mapStateToProps)(ChannelItem);
在我的例子中,channelList的频道已更新,因此我在MapStateTops中添加了chanelList

导出默认函数数据表({col,row}){
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}
    />
  );
}
const[datatable,setDatatable]=React.useState({}); useffect(()=>{ 可设置数据表({ 栏目:col, 行:行, }); ///还有别的事吗 },[世界其他地区]; 返回( ); }

本例使用
useffect
props
更改时更改状态。

在我的例子中,我正在更新传递给组件的
加载状态。在按钮中,
props.load
按预期进行(从false切换为true)但是显示旋转器没有更新的三元数据

我尝试添加一个键,添加一个使用useffect()等更新的状态,但其他答案都不起作用

对我起作用的是改变这一点:

setLoading(true);
handleOtherCPUHeavyCode();
为此:

setLoading(true);
setTimeout(() => { handleOtherCPUHeavyCode() }, 1)

我想这是因为handleOtherCPUHeavyCode中的过程非常繁重和密集,因此应用程序会冻结一秒钟左右。添加1ms超时可以更新加载布尔值,然后繁重的代码函数就可以完成它的工作。

我的案例涉及到在props对象上有多个属性,并且需要重新加载在给孩子换衣服的时候告诉他。 上面提供的解决方案是可行的,但为每个解决方案添加一个密钥变得单调乏味(想象一下有15个…)。如果有人面临这一问题,您可能会发现将道具对象字符串化很有用:

<Child
    key={JSON.stringify(props)}
/>

这样,道具上每个属性的每次更改都会触发子组件的重新渲染

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

export default connect(mapStateToProps)(ChannelItem);
希望对某人有所帮助。

您一定使用过动态组件。 在这个代码片段中,我们多次呈现子组件,并传递

  • 如果我们多次动态呈现一个组件,那么React不会呈现该组件,直到它的键被更改
如果使用setState方法更改选中的。在更改子组件的键之前,它不会反映在子组件中。我们必须在子组件的状态下保存它,然后相应地更改它以渲染子组件

类父级扩展组件{
状态={
核对:正确
}
render(){
返回(
{
[1,2,3]。地图(
<Child
    key={JSON.stringify(props)}
/>
componentWillReceiveProps({bar}) {
    this.setState({...this.state, bar})
}