状态更改时,React组件不会重新呈现

时间:2018-10-30 14:41:53

标签: javascript json reactjs

我有一个基于URL的react组件,应导入一些数据,然后将其显示在另一个子组件中。首次加载页面时,它将初始数据作为componentDidMount()中的组件状态加载。至于进一步的网址更改,它们将在componentDidUpdate()中处理 导出默认类信息扩展了React.Component {

constructor(props){
    super(props);
    this.state={
        element:null
    }
}

componentDidMount(){
    switch(this.props.match.params.id){
        case 'legende': import('../data/legends.json').then((data)=>{
            this.setState({
                element:(<InfoDisplay data={data.content} />)
            })
        });break;
        case 'istorie': import('../data/history.json').then((data) => {
            this.setState({
                element: (<InfoDisplay data={data.content} />)
            })
        }); break;
    }
}

componentDidUpdate(prevProps){
    if (this.props.match.params.id !== prevProps.match.params.id)
        switch (this.props.match.params.id) {
            case 'legende': import('../data/legends.json').then((data) => {
                this.setState({
                    element: (<InfoDisplay data={data.content} />)
                })
            });
            break;
            case 'istorie': import('../data/history.json').then((data) => {
                this.setState({
                    element: (<InfoDisplay data={data.content} />)
                })
            }); break;
        default: break;
        }
}

render(){
    return (
        <div style={{backgroundImage:`url(${background})`,height:'100vh',overflowX:'hidden',backgroundSize:'cover'}}>
            <Navbar/>
            {this.state.element}
        </div>
        )
    }
}

我的问题是,尽管switch语句中的状态已更新,但该组件不会重新呈现。我不知道我的方法有什么问题。有人可以帮我吗?谢谢!

编辑:这是使用shouldComponentUpdate()而不是componentDidUpdate的代码:

import React from 'react'
import * as background from '../assets/img/background_main.png';
import Navbar from './Navbar'
import InfoDisplay from './InfoDisplay';

export default class Info extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            element: null
        }
    }

    componentDidMount() {
        switch (this.props.match.params.id) {
            case 'legende': import('../data/legends.json').then((data) => {
                this.setState({
                    element: (<InfoDisplay data={data.content} />)
                })
            }); break;
            case 'istorie': import('../data/history.json').then((data) => {
                this.setState({
                    element: (<InfoDisplay data={data.content} />)
                })
            }); break;
        }
    }

    shouldComponentUpdate(nextProps,nextState) {
        if (this.props.match.params.id !== nextProps.match.params.id && nextProps) {
            switch (nextProps.match.params.id) {
                case 'legende': import('../data/legends.json').then((data) => {
                    this.setState({
                        element: (<InfoDisplay data={data.content} />)
                    })
                }); return true;
                case 'istorie': import('../data/history.json').then((data) => {
                    this.setState({
                        element: (<InfoDisplay data={data.content} />)
                    })
                });return true;
                default: return false;
            }
        }

        return true;
    }

    render() {
        return (
            <div style={{ backgroundImage: `url(${background})`, height: '100vh', overflowX: 'hidden', backgroundSize: 'cover' }}>
                <Navbar />
                {this.state.element}
            </div>
        )
    }
}

4 个答案:

答案 0 :(得分:1)

您可以真正简化并使其更清洁,这也可以解决您的问题:

在渲染中执行:

return (
    <div style={{backgroundImage:`url(${background})`,height:'100vh',overflowX:'hidden',backgroundSize:'cover'}}>
        <Navbar/>
        <InfoDisplay data={this.state.data} />
    </div>
    )

然后在componentDidMount和componentDidUpdate中,您要做的就是将状态数据设置为请求中的data.content:

 case 'legende': import('../data/legends.json').then((data) => {
            this.setState({
                data: data.content,
            });
        });

很显然,您还需要更改构造函数以获取数据:

this.state = {data: null};

希望这会有所帮助。

答案 1 :(得分:1)

您可能想使用shouldComponentUpdate,因为您想要做的是之前重新渲染组件。

检查一下: https://code.likeagirl.io/understanding-react-component-life-cycle-49bf4b8674de

http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

答案 2 :(得分:0)

如果重新渲染完成,将调用

componentDidUpdate()=> 实际上,就像您说的那样,没有重新渲染,因为您永远不会调用任何setState方法。

我不太确定某个状态是否可以保存JSX内容。

也许可以这样尝试:

this.setState({
    element: data.content
})

==

<div style={{backgroundImage:`url(${background})`,height:'100vh',overflowX:'hidden',backgroundSize:'cover'}}>
    <Navbar/>
    <InfoDisplay data={this.state.element} />
</div>

希望您会发现带有此信息的错误

答案 3 :(得分:0)

如果要在任何更新上重新渲染,则应使用

componentWillReceiveProps(nextProps){
  this.setState({element:nextProps.data})
}