《React-hook-useReducer》

244 阅读2分钟

useReducer是useState的复杂版,使用示例:

const intialState={
  n:0
}
const reducer=(state,action)=>{
  if(action.type==='add'){
    return {n:state.n+action.number}
  }else if(action.type==='multi'){
    return {n:state.n*2}
  }else{
    throw new Error('unknown')
  }
}

function App(){
  const [state,dispatch]=useReducer(reducer,intialState)
  const onClick=()=>{
    dispatch({type:'add',number:1})
  }
  const onClick2=()=>{
    dispatch({type:'add',number:2})
  }
  return (
    <div>
      n:{state.n}
      <button onClick={onClick}>+1</button>
      <button onClick={onClick2}>+2</button>
    </div>
  )
}

使用步骤:

  1. 创建初始值intialState
  2. 创建对state的所有操作的函数reducer(state,action)第一个参数state是现在的state,第二个参数action是一个对象,表示对数据进行的操作。通过判断action.type,返回不同的新state。这个action也可以有其他属性
  3. 调用userReducer(reducer,intialState),得到一个读数据API:state和一个写API:dispatch
  4. 在事件处理函数中,调用dispatch对数据修改。dispatch({type:'add',number:1}) dispatch传一个对象,就是action

什么时候可以用useReducer呢?如果使用useState时,要把多个变量组合在一起,也就是都放到一个对象里进行统一操作时,就可以改用useReducer

一个使用useReducer的表单例子:

const initFormData = {          // 1. 创建初始化数据
  name: "",
  age: 18,
  nationality: "汉族"
};

function reducer(state, action) {       // 2. 创建reducer函数,汇聚了所有操作
  switch (action.type) {
    case "patch":           // 更新数据
      return { ...state, ...action.formData };
    case "reset":           // 重置
      return initFormData;
    default:
      throw new Error();
  }
}

function App() {
  const [formData, dispatch] = useReducer(reducer, initFormData);  // 3.
  const onSubmit = () => {};
  const onReset = () => {
    dispatch({ type: "reset" });
  };
  return (
    <form onSubmit={onSubmit} onReset={onReset}>
      <div>
        <label>
          姓名
          <input value={formData.name}
            onChange={e =>
              dispatch({ type: "patch", formData: { name: e.target.value } })       
            }       // 4. 当用户往输入框里输入时,触发onChange事件,调用dispatch
          />        //修改formData的name
        </label>
      </div>
      <div>
        <label>
          年龄
          <input value={formData.age}
            onChange={e =>
              dispatch({ type: "patch", formData: { age: e.target.value } })
            }
          />
        </label>
      </div>
      <div>
        <label>
          民族
          <input value={formData.nationality}
            onChange={e =>
              dispatch({type: "patch", formData: { nationality: e.target.value }
              })
            }
          />
        </label>
      </div>
      <div>
        <button type="submit">提交</button>
        <button type="reset">重置</button>
      </div>
      <hr />
      {JSON.stringify(formData)}
    </form>
  );
}

由于每个input的value属性都读了formData里的对应属性,所以在输入框里输入,会在下边的展示区即时展示输入的新内容。