通过componentWillReceiveProps()实现React左右父子页面的联动效果

1.实现效果:

  • 通过单击左侧导航栏(父页面)内容,右侧(子页面)内容联动(呈现对应的导航栏内容),具体页面效果如下
  • 单击“几何图形初步”,右侧子页面显示“几何图形初步”

  • 单击"定义",右侧子页面显示"定义"

2.父页面Slider.js:单击具体列表导航栏抛出对应contentInformation redux,(通过react的antd组件库中的Tree组件实现列表导航栏效果),代码如下

  • 需要通过import { Tree } from 'antd'引入使用;
  • 定义:const TreeNode = Tree.TreeNode;
import React, { Component } from 'react';
import { Router, Route, hashHistory, IndexRoute, Redirect, IndexLink } from 'react-router';
import { Link, HashRouter } from 'react-router-dom';
import { connect } from 'react-redux';
import 'antd/dist/antd.css';  // Add
import { Layout, Menu, Breadcrumb, Icon, Tree, Button, Radio, Row, Col, Modal } from 'antd';
const { Header, Content, Footer, Sider } = Layout;
const TreeNode = Tree.TreeNode;
class Slider extends Component {
    // 状态机
    constructor(props, context) {
        super(props, context);
        this.state = {
	//列表导航栏数据
            treeData: [
                {
                    "title": "几何图形初步",
                    "isLeaf": false
                },
                {                    
                    "title": "一元一次方程",                    
                    "isLeaf": false
                },
                {
                    "title": "整式",
                    "isLeaf": false
                },
                {                 
                    "title": "有理数",                 
                    "isLeaf": false
                }
            ],
        }
    }
    onLoadData = (treeNode) => {
        return new Promise((resolve) => {
            if (treeNode.props.children) {
                resolve();
                return;
            }
            setTimeout(() => {
                treeNode.props.dataRef.children = [
                    { title: '定义' ,isLeaf: false },
                    { title: '概念' ,isLeaf: false  },
                ];
                this.setState({
                    treeData: [...this.state.treeData],
                });
                resolve();
            }, 1000);
        });
    }
    renderTreeNodes(data) {
        return data.map((item) => {
            if (item.children) {
                return (
                    {item.title}

} key={item.key} dataRef={item}> {this.renderTreeNodes(item.children)}
); } return {item.title}

} dataRef={item} />; }); } // 左侧导航栏单击事件,抛出redux即导航栏内容,供子页面接收 handleClick(title) { console.log('左侧导航栏-单击事件') const { contentInformation } = this.props; contentInformation ({ type: 'contentInformation ', payload: { content_title: title }, }); } render() { return ( {this.renderTreeNodes(this.state.treeData)} {this.props.children} //加载子页面所在位置 ); } } function mapStateToProps(state) { return { }; } function mapDispatchToProps(dispatch) { return { contentInformation : (state) => dispatch(state), //抛出redux }; } export default connect( mapStateToProps, mapDispatchToProps )(Slider);

3.子页面Detail.js:接收父页面传来的contentInformation redux,首次通过componentDidMount接收,非首次通过componentWillReceiveProps(nextProps)接收,代码如下

import React, { Component } from 'react';
import { Router, Route, hashHistory, IndexRoute, Redirect, IndexLink } from 'react-router';
import { Link, HashRouter } from 'react-router-dom';
import { connect } from 'react-redux';
import 'antd/dist/antd.css';  // Add
import { Card } from 'antd';
class Detail extends React.Component {
  // 状态机
  constructor(props, context) {
    super(props, context);
    this.state = {
      content: null,
    }
  }
//首次接收加载此周期函数
  componentDidMount() {  
    const { contentInformation } = this.props;
    const content_title= contentInformation.content_title;
    this.setState({ content: content_title});
  }
//非首次接收加载此周期函数,如果不使用此周期函数接收,子页面只能成功接收一次redux取值,因为componentDidMount不再重新加载,不了解此周期函数的使用,进一步学习可参考:http://blog.csdn.net/zrcj0706/article/details/78608740
  componentWillReceiveProps(nextProps) { 
    console.log("打印nextProps")
    console.log(nextProps)
    console.log(nextProps.contentInformation.content_title)
    this.setState({ content: nextProps.contentInformation.content_title});
  }
  render() {
    return (
      
{this.state.content}
); } } function mapStateToProps(state) { return { contentInformation: state.reducer_content.content.InformationInformation //接收redux }; } function mapDispatchToProps(dispatch) { return { }; } export default connect( mapStateToProps, mapDispatchToProps )(Detail);

4.通过react-router 4.2.0设置父子页面的路由关系

import React, { Component } from 'react';
import { Router, Route } from 'react-router';
import { Link, HashRouter } from 'react-router-dom';
import Slider from '../components/Slider.js';//左侧导航栏(父)页面
import Detail from '../components/Detail.js';//右侧内容(子)页面
export default class Routerindex extends Component {
    render() {
        return (
            
                               
            
        )
    }
}

5.设置redux

import { combineReducers } from 'redux'   //必须导入
function reducer_content(state = {}, action) {
    switch (action.type) {
        case 'contentInformation':
            console.log("contentInformation");
            console.log(action.payload);
            return { contentInformation: action.payload };
        default:
            return state;
    }
}

6.特别说明

  
  
    
    
    
    
  • componentWillReceiveProps使用时要加上nextProps参数,此函数通过该参数接收内容,不了解的可先打印后使用
  • 区别于componentDidMount函数的使用,正确使用
componentWillReceiveProps(nextProps) { 
    console.log("打印nextProps")
    console.log(nextProps)
    console.log(nextProps.contentInformation.content_title)
    this.setState({ content: nextProps.contentInformation.content_title});
  }
  • 而非如下使用
componentWillReceiveProps(nextProps) { 
    const { contentInformation } = this.props;
    const content_title= contentInformation.content_title;
    this.setState({ content: content_title});
  }








你可能感兴趣的:(react,父子页面联动,react联动效果,导航)