更新状态后组件不会重新渲染

Posted

技术标签:

【中文标题】更新状态后组件不会重新渲染【英文标题】:The component doesn't re-render after updating the state 【发布时间】:2019-06-17 16:08:54 【问题描述】:
componentDidMount()
    setInterval(()=>auth().get('/coordinates').then((res,err)=>
        if(err) throw err;
        console.log(res);
        let labels = [];
        let parts = [];
        for(let item of res.data)
            labels.push(item.time);
            parts.push(item.numberOfParts);
        
        let obj = this.getChartData(labels,parts);
        this.setState(chartData: obj);
    ).catch(err=>
        console.log(err);
    );
,10000)

我每隔 10 秒更新一次状态,但子组件没有用新更新的数据更新。

我尝试使用 forceUpdate(),但这也不起作用。在从 API 获得新响应后在控制台记录状态时,它会显示更新的内容,但不会重新呈现或更新子组件。

我计划在从 API 获取新数据时更新图表(子组件)。

这是完整的代码!

import React from 'react';
import LineChart from './Chart';
import auth from '../api/auth';

class Body extends React.Component 
constructor()
    super();
    this.state = 
        email:"",
        password:"",
        chartData:
    

getChartData(label, part)
    return 
        labels: label,
        datasets:[
          
            label:'Unix Timeline',
            data:part,
            backgroundColor:[
              'rgba(255, 99, 132, 0.6)',
              'rgba(54, 162, 235, 0.6)',
              'rgba(255, 206, 86, 0.6)',
              'rgba(75, 192, 192, 0.6)',
              'rgba(153, 102, 255, 0.6)',
              'rgba(255, 159, 64, 0.6)',
              'rgba(255, 99, 132, 0.6)'
            ]
          
        ]
      

componentDidMount()
    setInterval(()=>auth().get('/coordinates').then((res,err)=>
        if(err) throw err;
        console.log(res);
        let labels = [];
        let parts = [];
        for(let item of res.data)
            labels.push(item.time);
            parts.push(item.numberOfParts);
        
        let obj = this.getChartData(labels,parts);
        this.setState(chartData:obj);
    ).catch(err=>
        console.log(err);
    );,10000);  

onFormSubmission = (e)=>
    e.preventDefault();
    let creedentials =
        "email":`$this.state.email`,
        "password":`$this.state.password`
    
    auth().post('/user/signin',creedentials)
    .then((resp, err)=>
        if(err) throw err;
        this.props.signIn(resp.data.status);
    ).catch(err=>
        console.log(err);
    )


render()
    if(!this.props.signedIn)
    return (
        <div style= marginTop:"10vh", display:"flex",justifyContent:"center", flexDirection:"row">
            <div className="form-group shadow-lg p-3 mb-5 bg-white rounded" style=width:"400px", display:"flex", flexDirection:"column",padding:"20px">
                <legend>Login</legend>
                <label for="exampleInputEmail1">Email address</label>
                 <input value=this.state.email onChange=e=>this.setState(email:e.target.value) type="email" className="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email" required/>
                 <label for="exampleInputPassword1">Password</label>
                 <input value=this.state.password onChange=e=>this.setState(password:e.target.value) type="password" className="form-control" id="exampleInputPassword1" placeholder="Password" required></input>
                 <button onClick=this.onFormSubmission type="submit" className="btn btn-primary" style=marginTop:"10px", alignSelf:"center">Submit</button>
             </div>
         </div>
     );
    return (
        <div className="container" style=height:"50vh">
           <LineChart  chartData=this.state.chartData legendPosition="bottom"/>
        </div>
    );



export default Body;

【问题讨论】:

您使用哪个图表库?能贴出图表代码吗? 当然!我已经添加了! @kiranvj 我已经添加了代码 您确定您的状态是否正在更新,如果是,则问题出在 LineChart 组件上。你能发布LineChart的代码 【参考方案1】:

我认为你的问题在const obj = this.getChartData(labels,parts);

const替换成let

【讨论】:

问题依旧! 难以置信...检查我的测试 [链接] (jsfiddle.net/p6gncx54/2)

以上是关于更新状态后组件不会重新渲染的主要内容,如果未能解决你的问题,请参考以下文章

高阶组件状态正在正确更新,但接收道具的包装组件不会在状态更改时重新渲染

在条件渲染组件中,状态更新不会触发重新渲染。

React Native 和 Redux:为啥子组件不会在每次状态更新时重新渲染?

即使在状态更改后组件也不会更新

将新的商店状态放入道具后,反应不会重新渲染

React Native this.setState() 仅在再次与组件交互后重新渲染