0
votes

Pretty new to React and having some problems getting a child component to re-render after the parent state is changed. When I console.log the child component, I can see the updated property passed in from the parent, but the child component does not re-render after I setState. I've even tried calling forceUpdate (which I know is not the preferred way) but still no re-render.

Parent component:

export default class MainPanel extends React.Component {    
    constructor(props) {
        super(props);

        this.state = {
            preview: false,
        }
    }

     togglePreview = () => {
        this.setState({
            preview: !this.state.preview
        });
    }

    render() {
        return (
            <Layout className='section'>
                <Sider width={220} 
                    collapsedWidth={100}
                    collapsible
                    trigger={null}                  >
                    <Scrollbar noDefaultStyles={false}>
                        <SidebarMenu />
                    </Scrollbar>
                </Sider>
                <Divider type="vertical" className='divider vertical-divider' />
                <Layout className='section'>
                    <Header
                        preview={this.state.preview}
                        togglePreview={() => this.togglePreview()}
                    />
                    <Content preview={this.state.preview} />

                    <Footer>
                    </Footer>
                </Layout>
            </Layout>
        );
    }
}

Child component:

export default class Content extends React.PureComponent<ISectionProps, IBarProps> {
    constructor(props?:any) {
        super(props);
        this.state = {
          preview: props.preview,
          size: 7,
        };
    }

    componentWillReceiveProps(nextProps:any) {
        this.setState({ preview: nextProps.preview });
        console.log('nextProps: ' + nextProps.preview);
    }

    render()
    {
        return (
            <div id='content' className='layout-content'>
                <div className='content-wrapper'>
                    <Container className='content-container'>
                        <Section className='workspace' 
                            minSize={100}>
                            <Workspace />
                        </Section>
                        <Bar className='resizer' size={7} />
                        <Section className='preview' 
                            minSize={0} 
                            defaultSize={this.state.preview ? 1000 : 0 }>
                        </Section>
                    </Container>
                </div>
            </div>
        )
    }
}

Parent method togglePreview() updates the binding in <Content preview={this.state.preview} /> and in child method componentWillReceiveProps() correctly logs the updated true/false value which is bound to defaultSize={this.state.preview ? 1000 : 0 }> in the return. Everything seems to work except the component is not re-rendering with the updated defaultSize. I've also tried forceUpdate() as a callback in both parent and child components but that didn't work either.

Any help would me much obliged.

1

1 Answers

0
votes

It doesn't update because you set the state in the constructor, and the constructor only run once. Access the value directly from props.

 <Section className='preview' 
   minSize={0} 
   defaultSize={this.props.preview ? 1000 : 0 }>