React组件通信之打怪升级

151 阅读2分钟

React组件通信之打怪升级

Hello呀,我是樱乔。笔者很菜,如果有知识点理解错误的地方,请各位看官多多指教。
💕本周的内容是React组件间的通信。

一、组件通信(活化石版)

设置上下文信息
父组件:
childContextType——定义需要传递的属性数据类型
getChildContext()——返回对象就是context传递的属性
子组件:
contextTypes——定义子组件想要调用的属性数据类型
this.context——访问被contextTypes指定的父组件内容

class Complain extends React.Component {
  static contextTypes = {
    surface: PropTypes.string,
  };
  render() {
    return <div>{this.context.surface}</div>;
  }
}
class ComplainButton extends React.Component {
  static contextTypes = {
    realHeart: PropTypes.func,
  };
  render() {
    return (
      <>
        <button
          onClick={(ev) => {
            this.context.realHeart("好难啊!学吐了~~~");
          }}
        >
          真实想法
        </button>
      </>
    );
  }
}

export default class Father extends React.Component {
  static childContextTypes = {
    surface: PropTypes.string,
    realHeart: PropTypes.func,
  };
  getChildContext() {
    return {
      surface: this.state.surface,
      realHeart: this.realHeart,
    };
  }
  state = { surface: "前端很简单的,加油哦!!!" };
  realHeart = (myHeart) => {
    this.setState({
      surface: myHeart,
    });
  };
  render() {
    return (
      <div>
        <h3>来自小白的抱怨</h3>
        <Complain />
        <ComplainButton />
      </div>
    );
  }
}

二、组件通信(老古董版)

React.createContext——React大神提供的API
父组件:
ThemeContext.Provider——父组件注册上下文中的内容
子组件:
ThemeContext.Consumer——子组件进行消费(即获取上下文中内容)

//创建上下文对象
let ThemeContext = React.createContext();
//这是子组件第一种调用方式哦
class Complain extends React.Component {
  //将父组件提供的属性放在this.context中
  static contextTypes = ThemeContext;
  render() {
    return <div>{this.context.surface}</div>;
  }
}
//这是子组件第二种调用方式哟
class ComplainButton extends React.Component {
  render() {
    return (
      <ThemeContext.Consumer>
        {(context) => {
          return (
            <button
              onClick={(ev) => {
                context.realHeart("好难啊!学吐了~~~");
              }}
            >
              真实想法
            </button>
          );
        }}
      </ThemeContext.Consumer>
    );
  }
}

export default class Father extends React.Component {
  state = { surface: "前端很简单的,加油哦!!!" };
  realHeart = (myHeart) => {
    this.setState({
      surface: myHeart,
    });
  };
  //value传递上下文信息
  render() {
    return (
      <ThemeContext.Provider
        value={{
          surface: this.state.surface,
          realHeart: this.realHeart,
        }}
      >
        <h3>来自小白的抱怨</h3>
        <Complain />
        <ComplainButton />
      </ThemeContext.Provider>
    );
  }
}

三、组件通信(Redux版)

state——store容器中存储的当前状态
action——dispatch派发的行为对象
getState()——获取容器中的状态
subscribe([methods])——控制组件重新渲染(因此,该方法需要存储能重新渲染组件的方法)
reducer(state,action)——管理所有修改状态的操作
dispatch(action)——告知reducer修改状态

class Complain extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      ...props.store.getState(),
    };
  }
  componentDidMount() {
    this.setState({
      ...this.props.store.getState(),
    });
  }
  render() {
    return <div>{this.state.surface}</div>;
  }
}

class ComplainButton extends React.Component {
  store = this.props.store;
  render() {
    return (
      <button
        onClick={(ev) => {
          store.dispatch({
            type: "MY_HEART",
            surface: "好难啊!学吐了~~~",
          });
        }}
      >
        真实想法
      </button>
    );
  }
}

export default class Father extends React.Component {
  render() {
    let store = this.props.store,
      { surface } = store.getState();
    return (
      <div>
        <h3>来自小白的抱怨</h3>
        <Complain store={store} />
        <ComplainButton store={store} />
      </div>
    );
  }
}

//index.js中调用
const reducer = function (
  state = {
    surface: "前端很简单的,加油哦!!!",
  },
  action
) {
  state = JSON.parse(JSON.stringify(state));
  let surface = action.surface;
  switch (action.type) {
    case "MY_HEART":
      state.surface = surface;
      break;
    default:
      break;
  }
  return state;
};
const store = createStore(reducer);
ReactDom.render(
  <>
    <Father store={store} />
  </>,
  document.getElementById("root")
);

四、组件通信(React-Redux版)

Provider作用
将容器中的store放置到上下文,供子组件调用
connect作用
(1)将state和action作为属性赋值给某一组件
(2)包含subsribe功能
(3)页面渲染的组件为connect返回的代理组件
与redux相比较,优化点如下

//1.Provider包裹
ReactDOM.render(<Provider store={store}>
    <Vote />
</Provider>, document.getElementById('root'));
//2.connect封装
export default connect(state => ({...state.vote}), actions.vote)(Vote);
//=>第一个参数获取redux容器中的状态信息并挂载到组件属性上,通过props进行获取(this.props.father),相当于:
function mapStateToProps(state) {
    return {
        ...state.father
    };
}
//=>第二个参数将actions中的方法转换为派发格式,可以通过props直接调用方法完成派发任务(this.props.myHeart()),相当于:
function mapDispatchToProps(){
    return {
        myHeart(){
            dispatch(actions.father.myHeart());
        }
    }
}

886~ 下周见🌼