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

时间:2018-09-22 22:17:02

标签: javascript reactjs react-native

我要在父母的状态发生变化时重新呈现我的子组件而无需重新呈现父组件。

在此示例中,从未调用componentWillReceiveProps。

谢谢!


父组件

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

子组件

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

2 个答案:

答案 0 :(得分:2)

没有任何方法可以明确地提出您的建议。定义时:

shouldComponentUpdate(nextProps, nextState) {
    return false;
}

告诉Parent永远不要在初始渲染后重新渲染。但是,将道具传递到Child(以及促使Child重新呈现的动力)发生在render的{​​{1}}方法内部。因此,当您在Parent上阻止重新提交时,您也正在Parent的所有子级上阻止重新提交。

但是,不需要在Parent上进行重新渲染,因为React会尽可能少地修改DOM,因此您只会看到需要修改的父级部分的更改(由于更改)状态)。只要传递给Parent的其他子项(不是Parent的所有道具)保持不变,在Child调用中仅会修改Child

基本上,React已经可以处理您要尝试做的事情。

答案 1 :(得分:2)

为了用新的道具重新渲染子组件,必须重新渲染父组件。在这种情况下,通常没有理由不重新渲染父组件。 React旨在有效地做到这一点,并在可能的情况下在重新渲染时重用现有的DOM元素。

另一种方法是使子组件重新呈现其子组件,并使父组件以某种方式触发更新。这可以通过引用来完成,例如:

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

子组件保持其自身状态:

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

这里是demo

这是可以接受的解决方案,但会导致设计不那么直接。像原始代码一样,'Dumb'Child是执行此操作的首选方法,一般出于优化原因,不应更改此方法。如果在重新渲染Parent子项时遇到问题,则可能应采用其他方式解决。