简体   繁体   English

重新渲染react-redux组件

[英]Re-rendering react-redux component

I am using react-redux code structure and this is my first try with react-redux.I have cloned a github repository from Here and started editing it. 我正在使用react-redux代码结构,这是我对react-redux的第一次尝试。我已经从Here克隆了一个github存储库并开始对其进行编辑。

My directory structure: 我的目录结构:

在此处输入图片说明

Here schema is parent component and header and tables are 2 child components.Tables is showing data from localstorage through redux store. 模式是父组件,头和表是2个子组件。表显示了从本地存储到Redux存储的数据。

Initializing store: 初始化商店:

 const initialState = JSON.parse(window.localStorage.getItem('test'));
 const store = createStore(Reducers, initialState, compose(applyMiddleware(...middleware), extension));

Now an event is triggered from Header and sent to schema and in the response of this event schema is updating localstorage by requesting to server and saving server's response in localstorage as follows: 现在,从标头触发了一个事件并将其发送到架构,并且在此事件的响应中,架构通过请求服务器并将服务器的响应保存在localstorage中来更新本地存储,如下所示:

Schema.js: Schema.js:

class Schema extends PureComponent {
constructor(props) {
    super(props);
    this.table = ''; 
    getTables();       
}
myCallback = () => {//triggered by child(Header)
   getTables();       
}
getTables = () => {
  axios.get(url)
        .then((response) => {
            if(response.data.status==0){ 
 window.localStorage.setItem('test',JSON.stringify(response.data));
   this.tables=JSON.parse(window.localStorage.getItem('test'))
    });
}
render() {
 console.log(this.tables);//this is giving updated value at each updation
    return (
        <div className='container-fluid'>
            <Header callbackFromParent={ this.myCallback } />
            <br />
            <br />
            <Tables val={ this.tables } />
        </div>
    );
  }
}

Here is code for Tables.js: 这是Tables.js的代码

   class Tables extends Component {
   props: Props
   render() {
   let {tables,val } = this.props;
   console.log(JSON.parse(window.localStorage.getItem('test')));//this is giving updated value at each updation in localstorage
   console.log(val);//this is also giving updated value at each updation in localstorage
   tables=val;
   console.log(tables);this is also updating in realtime.      
   return (
        <div className='table-wrapper'>
            { tables.map((table) => (
                <Table
                    key={ table.id }
                    data={ table }
                />
            ))}
        </div>
       );
     }
   }

   type Props = {
     tables: Array<TableType>
   };

The issue is whenever header triggers callback, schema updates value of localstorage, this updation also re render Tables component. 问题是,每当标头触发回调,架构更新localstorage的值时,此更新也会重新呈现Tables组件。 Also an updated value can be seen in render of Tables component but the tables which are shown are from previous saved value. 还可以在“表格渲染”组件中看到更新的值,但是显示的表来自先前保存的值。 To get current value in tables, we need to refresh the page. 要获取表中的当前值,我们需要刷新页面。

is it a mistake in code flow or i need something else for this? 这是代码流中的错误还是为此我需要其他东西?

The idea is that react will trigger rendering of component whenever the component state or props is updated. 这个想法是,每当组件stateprops更新时,react就会触发组件的渲染。

If the component props are updated in parent component you will still need to update the component state to make the next render in inner component 如果组件props在父组件中已更新,则您仍将需要更新组件state以在内部组件中进行下一个渲染

The key of this is using componentWillReceiveProps 关键是使用componentWillReceiveProps

I updated your code with the code below: 我使用以下代码更新了您的代码:

Basically i did the following: 基本上我做了以下事情:

1- I used component state for Schema , Tables , and Table 1-我对SchemaTablesTable使用了组件状态

2- I used this.setState whenever i need to make updates to state (this is very important) 2-每当我需要更新状态时都使用this.setState (这非常重要)

3- I make sure that when a component props is updated in parent i update the component state as well using componentWillReceiveProps and this will make the new render with updated data 3-我确保在父级中更新组件props时,我也使用componentWillReceiveProps更新组件状态,这将使新的渲染器具有更新的数据

Schema component: 模式组件:

class Schema extends Component {
    constructor(props) {
        super(props);
        this.state = { tables : { } }
        this.getTables = this.getTables.bind(this);
        this.myCallback  = this.myCallback.bind(this);
    }

    componentWillMount(){
        this.getTables();
    }


    myCallback = () => {
       //triggered by child(Header)
       this.getTables();
    }


    getTables = () => {
      axios.get(url)
      .then((response) => {
            if(response.data.status==0)
            {
                window.localStorage.setItem('test',JSON.stringify(response.data));
                this.setState({
                    tables : JSON.parse(window.localStorage.getItem('test'))
                });
            }
        );
    }


    render() {
        //this is giving updated value at each updation
        console.log(this.state.tables);
        return (
            <div className='container-fluid'>
                <Header callbackFromParent={ this.myCallback } />
                <br />
                <br />
                <Tables tables={this.state.tables} />
            </div>
        );
    }
}

Tables Component 表格组件

 class Tables extends Component {
   constructor(props) {
        super(props);
        this.state = { tables : { }  }
    }


    componentWillMount(){
        this.setState({
            tables : this.props.tables
        })
    }


    componentWillReceiveProps(nextProps){
        this.setState({
            tables : nextProps.tables
        })
    }


   render() {
        console.log(JSON.parse(window.localStorage.getItem('test')));//this is giving updated value at each updation in localstorage
        console.log(this.state.tables);//this is also giving updated value at each updation in localstorage
       return (
            <div className='table-wrapper'>
                { this.state.tables.map((table) => (
                    <Table key={ table.id } data={ table } />
                ))
                }
            </div>
           );
    }
}

And finally a dummy Table component to show that you will also need to handle props update using componentWillReceiveProps to make sure each individual table component did render after props update 最后是一个虚拟的Table组件,以表明您还需要使用componentWillReceiveProps处理道具更新,以确保每个单独的表组件在props更新后props呈现

And probably this is where you have the issue ... because the tables are showing old data but the console.log of Tables component is logging new data which means Each individual Table component is not rending after the update 可能这就是您遇到的问题...因为表显示了旧数据,但是Tables组件的console.log正在记录新数据,这意味着每个单独的Table组件在更新后都没有保留

 class Table extends Component {
   constructor(props) {
        super(props);
        this.state = { data : { }  }
    }


    componentWillMount(){
        this.setState({
            data : this.props.data
        })
    }


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


   render() {
       console.log(this.state.data);
       return (
            <table className='table'>
                {this.state.data}
                //use your table data here
            </table>
           );
    }
}

Important Edit: 重要编辑:

As mentioned by react documentation componentWillReceiveProps might get called even if the props have not changed, thats why in some situation you might need to consider comparing this.props with nextProps to make sure that you really got new updated props and based on that you update the component state .... 正如提到的反应文档componentWillReceiveProps可能会被调用,即使道具都没有改变,这就是为什么在某些情况下,你可能需要考虑比较this.propsnextProps以确保你真的得到了新的更新, props ,并根据您更新组件state ....

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM