简体   繁体   English

仅在更改属性时才渲染子组件

[英]Render Only Child Component Only On Prop Change

I want to re-render my child component without re-rendering the parent component when the parent's state changes . 父级的状态更改时,我想重新渲染子级组件而不重新渲染父级组件。

In this example, componentWillReceiveProps is never called. 在此示例中,从不调用componentWillReceiveProps。

Thank You! 谢谢!


Parent Component 父组件

export default class Parent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            myValue: 'hello'
        }
    }

    shouldComponentUpdate(nextProps, nextState) {
        return false;
    }

    myFunction() {
        this.setState(prevState => {
          return {myValue: 'world'};
        });
    }

    render() {
        return (
            <View>
                <Button onPress={myFunction} title="Learn More"/>
                <Child myText={this.state.myValue}/>
            </View>
        );
    }
}

Child Component 子组件

export default class Child extends Component {
    constructor(props) {
        super(props);
    }

    componentWillReceiveProps(nextProps) {
        console.log('This Is Never Called');
    }

    render() {
        return (
            <View>
                <Text>{this.props.myText}</Text>
            </View>
        );
    }
}

There is no way to do what you are proposing explicitly. 没有办法明确地提出您的建议。 When you define: 定义时:

shouldComponentUpdate(nextProps, nextState) {
    return false;
}

are telling Parent never to rerender after its initial render. 告诉Parent永远不要在初始渲染后重新渲染。 However the passing of props to Child (and therefore the impetus for Child to rerender) happens inside the render method of Parent . 但是,将道具传递给Child (以及由此导致Child重新渲染的动力)发生在Parentrender方法内。 So when you block rerending on Parent you are also blocking rerendering on all children of Parent . 所以,当你阻止rerending的Parent ,你也阻止重新描绘上的所有儿童Parent

There is, however, no need to block rerendering on Parent because React will modify the DOM as little as possible, so you will only see changes in parts of parent that need to be modified (due to a change of state). 但是,由于在React会尽可能少地修改DOM,因此无需在Parent上阻止重新呈现,因此您只会看到需要修改的Parent部分的更改(由于状态更改)。 As long as all the props being passed to the other children of Parent (other than Child that is) remain unchanged, only Child will be modified in a Parent.render call. 只要传递给Parent的其他子代(而不是Child )的所有道具保持不变,在Parent.render调用中将仅修改Child

Basically React already handles what you are trying to do. 基本上,React已经可以处理您要尝试做的事情。

In order to re-render child component with new props, parent component has to be re-rendered. 为了用新的道具重新渲染子组件,必须重新渲染父组件。 There are generally no reasons to not re-render parent component in this situation. 在这种情况下,通常没有理由不重新渲染父组件。 React was designed to do this efficiently and reuse existing DOM elements on re-render where possible. React旨在有效地做到这一点,并在可能的情况下在重新渲染时重用现有的DOM元素。

The alternative approach is to make child component re-render its children and make parent component trigger the update somehow. 另一种方法是使子组件重新呈现其子组件,并使父组件以某种方式触发更新。 This can be done with refs, for instance: 例如,这可以通过引用来完成:

export default class Parent extends Component {
    state = {
        myValue: 'hello'
    }

    childRef = React.createRef();

    myFunction = () => {
        this.childRef.current.setText('world');
    }

    render() {
        return (
            <View>
                <Button onPress={this.myFunction} title="Learn More"/>
                <Child ref={this.childRef} myText={this.state.myValue}/>
            </View>
        );
    }
}

And child component maintains its own state: 子组件保持其自己的状态:

export default class Child extends Component {
    static getDerivedStateFromProps({ myText }, state) {
      return {myText, ...state};
    }

    setText(myText) {
      this.setState({ myText });
    }

    render() {
        return (
            <View>
                <Text>{this.state.myText}</Text>
            </View>
        );
    }
}

Here's a demo . 这是一个演示

This is acceptable solution but it results in less straightforward design. 这是可接受的解决方案,但会导致设计不那么直接。 'Dumb' Child like in original code is a preferable way to do this which shouldn't be changed for optimization reasons in general. “阿呆” Child像原来的代码是这样做的优选方式,不应在一般优化的原因而改变。 If there are problems with re-rendering Parent children, they possibly should be addressed in another way. 如果重新渲染Parent子女存在问题,则可能应该以其他方式解决。

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

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