当前位置: 首页 > 知识库问答 >
问题:

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

万俟宜修
2023-03-14

我有一个基于url的react组件,它应该导入一些数据,然后在另一个子组件中显示。当页面首次加载时,它将初始数据作为组件状态加载到componentDidMount()中。至于进一步的url更改,它们将在componentdiddupdate()export default class Info()中处理。组成部分{

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()而不是componentdiddupdate的代码:

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

共有3个答案

袁康裕
2023-03-14

如果重新呈现完成,将调用componentDidUpdate()=

我不太确定一个州是否可以保存JSX内容。

或许可以这样尝试:

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

==

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

希望您能通过这些信息找到您的bug

顾淳
2023-03-14

你真的可以简化它,让它更干净,这也应该解决你的问题:

在渲染中,请执行以下操作:

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

然后在componentDidMount和componentDidUpdate中,只需将状态数据设置为data。您请求的内容:

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

显然,为了获得数据,您还需要更改构造函数:

this.state = {data: null};

希望这有帮助。

晋安国
2023-03-14

您可能想要使用应该组件更新来代替,因为您想要的是在组件重新渲染之前做一些事情。

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

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

 类似资料:
  • 我有一个带有两组按钮(功能和目标)的界面。当我点击一个按钮时,我希望它从一个团队转到另一个团队。我正在用react和redux实现这一点。我唯一的问题是,当状态更新并且我成功地记录了更新的状态时,除非我使用forceUpdate(),否则组件不会更新。我不明白的是,既然状态更新成功,组件不应该自动重新渲染吗? 一些js 正如您所看到的,当我单击一个按钮时,我触发updateLists函数,该函数将

  • 问题内容: 我从React中学到的一件事是,如果组件的属性不变,那么React不会重新渲染组件。无状态组件也是如此吗?还是它们的行为更像“愚蠢的”函数,并且每次都会执行? 例如,如果我有: 当更新其价值,并获取重新渲染?还是像其他React组件一样足够“聪明”地看到其道具没有改变? 问题答案: 更新25.10.2018 从React 16.6开始,您可以将React.memo用于功能组件以防止重新

  • 我试图将表示组件与容器组件分开。我有一个和一个。容器负责触发redux操作,以基于当前用户获取适当的站点。 问题在于,在容器组件最初呈现之后,当前用户是异步获取的。这意味着容器组件不知道需要在其函数中重新执行代码,该函数将更新数据以发送到。我想当容器组件的一个道具(用户)发生变化时,我需要重新渲染它。如何正确地执行此操作?

  • 我是reactjs的新手,我不知道如何从父组件中更改子组件的状态。下面是代码 每当对父组件中的执行时,我希望子组件接收。 有什么建议吗?

  • <罢工> 是否存在这样的情况:父组件将新道具传递给子组件,导致子组件重新呈现,但这不是简单地由父组件重新呈现引起的? 有没有可能看到这样一个例子:组件会因为接收到新的道具而重新呈现,而不是因为父组件正在重新呈现(或者它自己的状态改变了)? 对不起,如果这是一个基本的问题,我是新的反应。

  • 问题内容: 我要说的是今天要学习react和redux,但是我不知道如何在状态更改后强制组件重新渲染。 这是我的代码: 我可以触发更新的唯一方法是使用 在构造函数内部,以便我手动触发组件的更新状态以强制重新渲染。 但是如何链接存储状态和组件状态? 问题答案: 仅当组件的状态或道具发生更改时,组件才会重新渲染。您不是依靠this.state或this.props,而是直接在render函数中获取存储