react组件间通信(含实例)

下面用一个例子来说明https://github.com/zhengmiaohua/my-react-demos

 

第一种:父组件向子组件传递数据,一般用props,子组件想要改变父组件的数组,可以向子组件传递回调函数,层级多的话嵌套会很复杂

//stuScore1.html

const SCORE=[
                {name: '张三', gender: '男', chinese: 85, math: 98, id:0},
                {name: '张三', gender: '女', chinese: 95, math: 90, id:1},
                {name: '李四', gender: '男', chinese: 65, math: 48, id:2},
                   {name: '大妹', gender: '女', chinese: 95, math: 100,id:3},
                {name: '王五', gender: '男', chinese: 75, math: 88, id:4},
                {name: '赵钱', gender: '男', chinese: 75, math: 98, id:5},
                {name: '二妹', gender: '女', chinese: 90, math: 98, id:6}
        ];
        class StudentScoreTable extends React.Component{
            constructor(props){
                super(props);
                this.state={
                    genderFilter:0,
                    nameFilter:''
                }
                this.onGenderChange=this.onGenderChange.bind(this);
                this.onNameChange=this.onNameChange.bind(this);
            }
            onGenderChange(gender){
                this.setState({genderFilter:gender});
            }
            onNameChange(name){
                this.setState({nameFilter:name})
            }
            render(){
                return (
                    <div>
                        <GenderInputBar onGenderChange={this.onGenderChange} genderFilter={this.genderFilter}/>
                        <NameInputBar onNameChange={this.onNameChange} nameFilter={this.nameFilter}/>
                        <ScoreTable scoreArr={this.props.score} genderFilter={this.state.genderFilter} nameFilter={this.state.nameFilter}/>
                    </div>
                );
            }
        }

        class ScoreTable extends React.Component{
            constructor(props){
                super(props);

            }
            render(){
                let rows=[];
                let genderFilter=this.props.genderFilter;
                let nameFilter=this.props.nameFilter;
                const GENDER=['','男','女']
                this.props.scoreArr.map((scoreItem)=>{
                    if(genderFilter!==0&&nameFilter===''){
                        if(scoreItem.gender===GENDER[genderFilter]){
                            rows.push(<ScoreItem score={scoreItem} key={scoreItem.id}/>)
                        }
                        return;
                    }
                    if(genderFilter===0&&nameFilter!==''){
                        if(scoreItem.name===nameFilter){
                            rows.push(<ScoreItem score={scoreItem} key={scoreItem.id} />)
                        }
                        return;
                    }
                    if(genderFilter!==0&&nameFilter!==''){
                        if(scoreItem.gender===GENDER[genderFilter]&&scoreItem.name===nameFilter){
                            rows.push(<ScoreItem score={scoreItem} key={scoreItem.id} />)
                        }
                        return;
                    }
                    rows.push(<ScoreItem score={scoreItem} key={scoreItem.id} />)

                })
                return (
                    <table className="gridtable">
                        <thead>
                            <tr>
                                <th>姓名</th>
                                <th>性别</th>
                                <th>语文</th>
                                <th>数学</th>
                            </tr>
                        </thead>
                        <tbody>
                            {rows}
                        </tbody>
                    </table>
                );
            }
        }

        class ScoreItem extends React.Component{
            constructor(props){
                super(props);
            }
            render(){
                let score=this.props.score;
                return (
                    <tr>
                        <td>{score.name}</td>
                        <td>{score.gender}</td>
                        <td>{score.chinese}</td>
                            <td>{score.math}</td>
                    </tr>
                );
            }
        }

        class GenderInputBar extends React.Component{
            constructor(props){
                super(props);
                this.genderChangeHandler=this.genderChangeHandler.bind(this);
            }
            genderChangeHandler(e){
                this.props.onGenderChange(e.target.value);
            }
            render(){
                return (
                    <div>
                        <from>
                            <label>按性别筛选:</label>
                            <select onChange={this.genderChangeHandler}>
                                <option value="0">All</option>
                                <option value="1">男</option>
                                <option value="2">女</option>
                            </select>
                        </from>
                    </div>
                );
            }
        }

        class NameInputBar extends React.Component{
            constructor(props){
                super(props);
                this.nameChangeHandler=this.nameChangeHandler.bind(this)
            }
            nameChangeHandler(e){
                this.props.onNameChange(e.target.value)
            }
            render(){
                return (
                    <div>
                        <form>
                            <label htmlFor="nameInput">按姓名筛选:</label>
                            <input type="text" id="nameInput" value={this.props.nameFilter} onChange={this.nameChangeHandler} />
                        </form>
                    </div>
                );
            }
        }
        
        ReactDOM.render(
            <StudentScoreTable score={SCORE} />,
            document.getElementById("root"));
    </script>

 

 第二种:直接通过其组件句柄去直接访问其方法,没有了中间环节,代码也简洁了很多,把this指向赋给一个全局变量

//stuScore1.html

const SCORE=[
                {name: '张三', gender: '男', chinese: 85, math: 98, id:0},
                {name: '张三', gender: '女', chinese: 95, math: 90, id:1},
                {name: '李四', gender: '男', chinese: 65, math: 48, id:2},
                   {name: '大妹', gender: '女', chinese: 95, math: 100,id:3},
                {name: '王五', gender: '男', chinese: 75, math: 88, id:4},
                {name: '赵钱', gender: '男', chinese: 75, math: 98, id:5},
                {name: '二妹', gender: '女', chinese: 90, math: 98, id:6}
        ];
        var _StudentScoreTable=null;
        class StudentScoreTable extends React.Component{
            constructor(props){
                super(props);
                this.state={
                    genderFilter:0,
                    nameFilter:''
                }
                //把StudentScoreTable组件赋值给一个变量,以便在其它组件中可以使用此组件的方法,直接通过其组件句柄去直接访问其方法
                _StudentScoreTable=this;
                this.onGenderChange=this.onGenderChange.bind(this);
                this.onNameChange=this.onNameChange.bind(this);
            }
            onGenderChange(gender){
                this.setState({genderFilter:gender});
            }
            onNameChange(name){
                this.setState({nameFilter:name})
            }
            render(){
                return (
                    <div>
                        <GenderInputBar genderFilter={this.genderFilter}/>
                        <NameInputBar nameFilter={this.nameFilter}/>
                        <ScoreTable scoreArr={this.props.score} genderFilter={this.state.genderFilter} nameFilter={this.state.nameFilter}/>
                    </div>
                );
            }
        }

        class ScoreTable extends React.Component{
            constructor(props){
                super(props);

            }
            render(){
                let rows=[];
                let genderFilter=this.props.genderFilter;
                let nameFilter=this.props.nameFilter;
                const GENDER=['','男','女']
                this.props.scoreArr.map((scoreItem)=>{
                    if(genderFilter!==0&&nameFilter===''){
                        if(scoreItem.gender===GENDER[genderFilter]){
                            rows.push(<ScoreItem score={scoreItem} key={scoreItem.id}/>)
                        }
                        return;
                    }
                    if(genderFilter===0&&nameFilter!==''){
                        if(scoreItem.name===nameFilter){
                            rows.push(<ScoreItem score={scoreItem} key={scoreItem.id} />)
                        }
                        return;
                    }
                    if(genderFilter!==0&&nameFilter!==''){
                        if(scoreItem.gender===GENDER[genderFilter]&&scoreItem.name===nameFilter){
                            rows.push(<ScoreItem score={scoreItem} key={scoreItem.id} />)
                        }
                        return;
                    }
                    rows.push(<ScoreItem score={scoreItem} key={scoreItem.id} />)

                })
                return (
                    <table className="gridtable">
                        <thead>
                            <tr>
                                <th>姓名</th>
                                <th>性别</th>
                                <th>语文</th>
                                <th>数学</th>
                            </tr>
                        </thead>
                        <tbody>
                            {rows}
                        </tbody>
                    </table>
                );
            }
        }

        class ScoreItem extends React.Component{
            constructor(props){
                super(props);
            }
            render(){
                let score=this.props.score;
                return (
                    <tr>
                        <td>{score.name}</td>
                        <td>{score.gender}</td>
                        <td>{score.chinese}</td>
                            <td>{score.math}</td>
                    </tr>
                );
            }
        }

        class GenderInputBar extends React.Component{
            constructor(props){
                super(props);
                this.genderChangeHandler=this.genderChangeHandler.bind(this);
            }
            genderChangeHandler(e){
                _StudentScoreTable.onGenderChange(e.target.value);
            }
            render(){
                return (
                    <div>
                        <from>
                            <label>按性别筛选:</label>
                            <select onChange={this.genderChangeHandler}>
                                <option value="0">All</option>
                                <option value="1">男</option>
                                <option value="2">女</option>
                            </select>
                        </from>
                    </div>
                );
            }
        }

        class NameInputBar extends React.Component{
            constructor(props){
                super(props);
                this.nameChangeHandler=this.nameChangeHandler.bind(this)
            }
            nameChangeHandler(e){
                _StudentScoreTable.onNameChange(e.target.value)
            }
            render(){
                return (
                    <div>
                        <form>
                            <label htmlFor="nameInput">按姓名筛选:</label>
                            <input type="text" id="nameInput" value={this.props.nameFilter} onChange={this.nameChangeHandler} />
                        </form>
                    </div>
                );
            }
        }
        
        ReactDOM.render(
            <StudentScoreTable score={SCORE} />,
            document.getElementById("root"));
    </script>

第三种:发布订阅模式

//stuScore2.html

// eventProxy.js首先使用数组缓存订阅者订阅的消息,当订阅者订阅消息的时候,把订阅的消息push到指定消息的队列中,当发布者发布消息的时候,我们遍历执行push到指定消息队列中的回调事件。
        'use strict';
        const eventProxy = {
          onObj: {},
          oneObj: {},
          on: function(key, fn) {
            if(this.onObj[key] === undefined) {
              this.onObj[key] = [];
            }

            this.onObj[key].push(fn);
          },
          one: function(key, fn) {
            if(this.oneObj[key] === undefined) {
              this.oneObj[key] = [];
            }

            this.oneObj[key].push(fn);
          },
          off: function(key) {
            this.onObj[key] = [];
            this.oneObj[key] = [];
          },
          trigger: function() {
            let key, args;
            if(arguments.length == 0) {
              return false;
            }
            key = arguments[0];
            args = [].concat(Array.prototype.slice.call(arguments, 1));

            if(this.onObj[key] !== undefined
              && this.onObj[key].length > 0) {
              for(let i in this.onObj[key]) {
                this.onObj[key][i].apply(null, args);
              }
            }
            if(this.oneObj[key] !== undefined
              && this.oneObj[key].length > 0) {
              for(let i in this.oneObj[key]) {
                this.oneObj[key][i].apply(null, args);
                this.oneObj[key][i] = undefined;
              }
              this.oneObj[key] = [];
            }
          }
        };
        const GenderFilterChangeEvt = 'genderFilter change event';
        const NameFilterChangeEvt = 'nameFilter change event';
        const SCORE=[
                {name: '张三', gender: '男', chinese: 85, math: 98, id:0},
                {name: '张三', gender: '女', chinese: 95, math: 90, id:1},
                {name: '李四', gender: '男', chinese: 65, math: 48, id:2},
                   {name: '大妹', gender: '女', chinese: 95, math: 100,id:3},
                {name: '王五', gender: '男', chinese: 75, math: 88, id:4},
                {name: '赵钱', gender: '男', chinese: 75, math: 98, id:5},
                {name: '二妹', gender: '女', chinese: 90, math: 98, id:6}
        ];
        class StudentScoreTable extends React.Component{
            constructor(props){
                super(props);
                this.state={
                    genderFilter:0,
                    nameFilter:''
                }
                this.onGenderChange=this.onGenderChange.bind(this);
                this.onNameChange=this.onNameChange.bind(this);
            }
            onGenderChange(gender){
                this.setState({genderFilter:gender});
            }
            onNameChange(name){
                this.setState({nameFilter:name})
            }
            componentDidMount(){
                eventProxy.on(GenderFilterChangeEvt,this.onGenderChange);
                eventProxy.on(NameFilterChangeEvt,this.onNameChange);
            }
            render(){
                return (
                    <div>
                        <GenderInputBar genderFilter={this.genderFilter}/>
                        <NameInputBar nameFilter={this.nameFilter}/>
                        <ScoreTable scoreArr={this.props.score} genderFilter={this.state.genderFilter} nameFilter={this.state.nameFilter}/>
                    </div>
                );
            }
        }

        class ScoreTable extends React.Component{
            constructor(props){
                super(props);

            }
            render(){
                let rows=[];
                let genderFilter=this.props.genderFilter;
                let nameFilter=this.props.nameFilter;
                const GENDER=['','男','女']
                this.props.scoreArr.map((scoreItem)=>{
                    if(genderFilter!==0&&nameFilter===''){
                        if(scoreItem.gender===GENDER[genderFilter]){
                            rows.push(<ScoreItem score={scoreItem} key={scoreItem.id}/>)
                        }
                        return;
                    }
                    if(genderFilter===0&&nameFilter!==''){
                        if(scoreItem.name===nameFilter){
                            rows.push(<ScoreItem score={scoreItem} key={scoreItem.id} />)
                        }
                        return;
                    }
                    if(genderFilter!==0&&nameFilter!==''){
                        if(scoreItem.gender===GENDER[genderFilter]&&scoreItem.name===nameFilter){
                            rows.push(<ScoreItem score={scoreItem} key={scoreItem.id} />)
                        }
                        return;
                    }
                    rows.push(<ScoreItem score={scoreItem} key={scoreItem.id} />)

                })
                return (
                    <table className="gridtable">
                        <thead>
                            <tr>
                                <th>姓名</th>
                                <th>性别</th>
                                <th>语文</th>
                                <th>数学</th>
                            </tr>
                        </thead>
                        <tbody>
                            {rows}
                        </tbody>
                    </table>
                );
            }
        }

        class ScoreItem extends React.Component{
            constructor(props){
                super(props);
            }
            render(){
                let score=this.props.score;
                return (
                    <tr>
                        <td>{score.name}</td>
                        <td>{score.gender}</td>
                        <td>{score.chinese}</td>
                            <td>{score.math}</td>
                    </tr>
                );
            }
        }

        class GenderInputBar extends React.Component{
            constructor(props){
                super(props);
                this.genderChangeHandler=this.genderChangeHandler.bind(this);
            }
            genderChangeHandler(e){
                eventProxy.trigger(GenderFilterChangeEvt,e.target.value);
            }
            render(){
                return (
                    <div>
                        <from>
                            <label>按性别筛选:</label>
                            <select onChange={this.genderChangeHandler}>
                                <option value="0">All</option>
                                <option value="1">男</option>
                                <option value="2">女</option>
                            </select>
                        </from>
                    </div>
                );
            }
        }

        class NameInputBar extends React.Component{
            constructor(props){
                super(props);
                this.nameChangeHandler=this.nameChangeHandler.bind(this)
            }
            nameChangeHandler(e){
                eventProxy.trigger(NameFilterChangeEvt,e.target.value);
            }
            render(){
                return (
                    <div>
                        <form>
                            <label htmlFor="nameInput">按姓名筛选:</label>
                            <input type="text" id="nameInput" value={this.props.nameFilter} onChange={this.nameChangeHandler} />
                        </form>
                    </div>
                );
            }
        }
        
        ReactDOM.render(
            <StudentScoreTable score={SCORE} />,
            document.getElementById("root"));
    </script>

 

posted @ 2017-08-20 19:07  郑庙华  阅读(490)  评论(0编辑  收藏  举报