繁体   English   中英

在 React.js 中触发子重新渲染

[英]Trigger child re-rendering in React.js

父( MyList在我的例子)组件呈现直通一个孩子(阵列MyComponent )组件。 父级决定更改数组中的属性,React 触发子级重新渲染的方式是什么?

我想出的只是this.setState({}); 调整数据后在 Parent 中。 这是 hack 还是 React 触发更新的方式?

JS小提琴: https : //jsfiddle.net/69z2wepo/7601/

var items = [
  {id: 1, highlighted: false, text: "item1"},
  {id: 2, highlighted: true, text: "item2"},
  {id: 3, highlighted: false, text: "item3"},
];

var MyComponent = React.createClass({
  render: function() {
    return <div className={this.props.highlighted ? 'light-it-up' : ''}>{this.props.text}</div>;
  }
});

var MyList = React.createClass({
  toggleHighlight: function() {
    this.props.items.forEach(function(v){
      v.highlighted = !v.highlighted;
    });

    // Children must re-render
    // IS THIS CORRECT?
    this.setState({});
  },

  render: function() {
    return <div>
      <button onClick={this.toggleHighlight}>Toggle highlight</button>
      {this.props.items.map(function(item) {
          return <MyComponent key={item.id} text={item.text} highlighted={item.highlighted}/>;
      })}
    </div>;
  }
});

React.render(<MyList items={items}/>, document.getElementById('container'));

这里的问题是你在this.props而不是this.state存储状态。 由于此组件正在改变items ,因此items是 state 并且应该存储在this.state (这是一篇关于 props 与 state好文章。)这解决了您的渲染问题,因为当您更新items您将调用setState ,它会自动触发重新渲染。

下面是你的组件使用 state 而不是 props 的样子:

var MyList = React.createClass({
    getInitialState: function() {
        return { items: this.props.initialItems };
    },

    toggleHighlight: function() {
        var newItems = this.state.items.map(function (item) {
            item.highlighted = !item.highlighted;
            return item;
        });

        this.setState({ items: newItems });
    },

    render: function() {
        return (
            <div>
                <button onClick={this.toggleHighlight}>Toggle highlight</button>
                { this.state.items.map(function(item) {
                    return <MyComponent key={item.id} text={item.text} 
                             highlighted={item.highlighted}/>;
                }) }
            </div>
        );    
    }
});

React.render( <MyList initialItems={initialItems}/>,
              document.getElementById('container') );

请注意,我改名items道具initialItems ,因为它清楚地表明, MyList会发生变异它。 这是文档推荐的

你可以在这里看到更新的小提琴: https : //jsfiddle.net/kxrf5329/

我找到了一个很好的解决方案,使用key属性重新渲染React Hook 如果我们更改了子组件或 React 组件的某些部分的关键属性,它将完全重新渲染。 当您需要重新渲染 React 组件的某些部分或重新渲染子组件时,它将使用它。 这是一个例子。 我将重新渲染完整的组件。

import React, { useState, useEffect } from "react";
import { PrEditInput } from "./shared";

const BucketInput = ({ bucketPrice = [], handleBucketsUpdate, mood }) => {
  const data = Array.isArray(bucketPrice) ? bucketPrice : [];
  const [state, setState] = useState(Date.now());
  useEffect(() => {
    setState(Date.now());
  }, [mood, bucketPrice]);
  return (
    <span key={state}>
      {data.map((item) => (
        <PrEditInput
          key={item.id}
          label={item?.bucket?.name}
          name={item.bucketId}
          defaultValue={item.price}
          onChange={handleBucketsUpdate}
          mood={mood}
        />
      ))}
    </span>
  );
};

export default BucketInput;

您应该通过调用setState()并提供要向下传播的新道具来触发重新渲染。 如果你真的想强制更新,你也可以调用forceUpdate()

如果您查看此页面上的示例,您会发现setState是用于更新和触发重新渲染的方法。 文档也清楚地说明了(啊哈!)。

在你的情况下,我会打电话给forceUpdate

编辑:正如 Jordan 在评论中提到的,最好将物品作为您所在州的一部分进行存储。 这样你就不必调用forceUpdate但你真的会更新组件的状态,因此具有更新值的常规setState会更好地工作。

重新渲染子项的一个简单选项是每次需要重新渲染时更新唯一的键属性。

<ChildComponent key={this.state.updatedKey}/>

您可以在子组件上设置数字键,并在执行操作后触发键更改。 例如

state = {
        childKey: 7,
};



<ChildComponent key={this.state.childKey}/>


actionToTriggerReload = () => {
const newKey = this.state.childKey * 89; // this will make sure the key are never the same
this.setState({childKey: newKey})
   }

这肯定会重新渲染 ChildComponent

在子组件中设置数字默认“键”并重新渲染只需更改键值。

this.state = {
        updatedKey: 1,
};    
triggerReload = () => {
let newKey = Math.floor(Math.random() * 100); // make sure the key are never the same
this.setState({updatedKey: newKey})
   }
<childComponent key={this.state.updatedKey} handlerProp = {this.onClickItemEvent} />

这对我在 reactjs 类库中重新渲染 ChildComponent 有用

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM