当状态改变时,React 组件不会重新渲染

IT技术 javascript json reactjs
2021-05-08 07:08:29

我有一个基于 url 的 react 组件,它应该导入一些数据,然后将其显示在另一个子组件中。当页面第一次加载时,它加载初始数据作为componentDidMount(). 至于进一步的 url 更改,它们在componentDidUpdate() 导出默认类 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;
    }
}

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个回答

您可能想shouldComponentUpdate改用,因为您想要的是重新渲染组件之前做一些事情

看看这个:https : //code.likeagirl.io/understanding-react-component-life-cycle-49bf4b8674de

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

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

在你的渲染中做:

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

希望这可以帮助。

如果重新渲染完成,将调用 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>

希望你能用这些信息找到你的错误

如果你想重新渲染任何更新,那么你应该使用

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