标签: React

  • React Context

    Context 的目的是对于全局的需要多处使用的数据,不希望通过 prop 一层层传递下去,而是可以直接使用。

    childContextTypes & getChildContext

    该方案在 16.3 后不再是推荐方案。

    React 最初提供的 context 方案是提供 context 数据的组件通过静态的 childContextType 来定义 context 中各字段的数据类型,通过 getChildContext 成员方法来提供实际的 context 数据,其中,返回的数据可以搭配 prop 和 state 来提供响应式的数据。而消费 context 数据的组件通过静态的 contextTypes 来指定需要消费的 context 字段的类型集合,然后即可通过 this.context[fieldName] 来使用。

    注意,消费 context 的组件只需要定义需要的字段的类型即可,不需要是全部。同时,也不需要是提供 context 的组件的直接子组件。

    import PropTypes from 'prop-types';
    
    class Button extends React.Component {
      static contextTypes = {
        color: PropTypes.string
      };
    
      render() {
        return (
          <button style={{background: this.context.color}}>
            {this.props.children}
          </button>
        );
      }
    }
    
    class Message extends React.Component {
      render() {
        return (
          <div>
            {this.props.text} <Button>Delete</Button>
          </div>
        );
      }
    }
    
    class MessageList extends React.Component {
      static childContextTypes = {
        color: PropTypes.string
      };
    
      getChildContext() {
        return {color: "purple"};
      }
    
      render() {
        const children = this.props.messages.map((message) =>
          <Message text={message.text} />
        );
        return <div>{children}</div>;
      }
    }
    

    (更多…)

  • React 行内条件渲染

    React 的行内条件渲染(inline conditional rendering)能够在无 else 分支的情况下简化条件渲染,这是由子元素定义及渲染决定的。

    const ele = (
      <div>
        <p>{true}</p>
        <p>{true && 1}</p>
    
        <p>{false}</p>
        <p>{false && 2}</p>
      </div>
    );
    

    对应的 JavaScript 代码是

    const ele = React.createElement(
      "div",
      null,
      React.createElement("p", null, true),
      React.createElement("p", null, true && 1),
      React.createElement("p", null, false),
      React.createElement("p", null, false && 2)
    );
    

    true && 1 等的表达式结果作为子元素去渲染时,使用  ChildReconciler#createChild ,其中仅当子元素类型(typeof)是 stringnumberobject 且不为 null 时才渲染,所以 true / false 则不会渲染。

    (更多…)

  • 单 Store 单页应用的状态重置

    如果是基于 Redux 等单 Store 形式来构建单页应用,那么需要注意,大多数时候,切换页面时(如前进、后退或直接访问),需要注意状态的重置。

    如果用的是 react-router-redux,那么需要在切换后做 reset 的页面的 reducer 中,在 actionLOCATION_CHANGE1 时,返回该 reducer 的 initState。如:

    // reducers/page1.js
    import { LOCATION_CHANGE } from 'react-router-redux';
    import * as actions from '../../actions/page1';
    
    const initialState = {
      list: ['默认文本'],
    };
    
    export default function index(state = initialState, action) {
      switch (action.type) {
        case LOCATION_CHANGE:
          return initialState;
    
        case actions.ADD_TEXT:
    
          return Object.assign({}, state, {
            list: [action.data, ...state.list],
          });
    
        default:
          return state;
      }
    }
    

    如果用的是 connected-react-router,也类似。

    // reducers/counter.js
    import { LOCATION_CHANGE } from 'connected-react-router';
    
    const counterReducer = (state = 0, action) => {
      switch (action.type) {
        case LOCATION_CHANGE:
          return 0;
        case 'INCREMENT':
          return state + 1
        case 'DECREMENT':
          return state - 1
        default:
          return state
      }
    }
    
    export default counterReducer
    

    (更多…)