重新渲染react-redux组件

时间:2017-10-12 17:18:43

标签: reactjs redux local-storage

我正在使用react-redux代码结构,这是我第一次尝试使用react-redux。我已经克隆了一个github存储库from Here并开始编辑它。

我的目录结构:

enter image description here

这里的模式是父组件和标题,表是2个子组件。表从localstorage到redux商店显示数据。

初始化商店:

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

现在,一个事件从Header触发并发送到模式,并且在此事件模式的响应中,通过请求服务器并在localstorage中保存服务器的响应来更新localstorage,如下所示:

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

以下是 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>
   };

问题是每当标头触发回调,架构更新localstorage的值时,此更新也会重新呈现Tables组件。在表组件的呈现中也可以看到更新的值,但显示的表来自先前保存的值。要获取表中的当前值,我们需要刷新页面。

这是代码流中的错误还是我还需要其他东西?

1 个答案:

答案 0 :(得分:0)

我们的想法是,每当组件stateprops更新时,react都会触发组件的呈现。

如果组件props在父组件中更新,您仍需要更新组件state以在内部组件中进行下一次渲染

关键是使用componentWillReceiveProps

我使用以下代码更新了您的代码:

基本上我做了以下事情:

1-我使用了SchemaTablesTable

的组件状态

2-每当我需要对状态进行更新时,我使用this.setState

3-我确保在父级更新组件props时,我也使用componentWillReceiveProps更新组件状态,这将使新的渲染更新数据

架构组件:

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

表组件

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

最后是一个虚拟的Table组件,表明你还需要使用componentWillReceiveProps处理props更新,以确保每个单独的表组件在props更新后呈现

可能这就是您遇到问题的地方......因为这些表显示旧数据但console.log Tables组件正在记录新数据,这意味着每个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>
           );
    }
}

重要编辑:

正如反应文档componentWillReceiveProps所提到的那样即使道具没有改变也可能被调用,这就是为什么在某些情况下你可能需要考虑将this.propsnextProps进行比较以确保您确实获得了新的更新props并基于此更新了组件state ....