首页 > 解决方案 > 当调度将状态更新为与当前相同的操作时,如何触发效果?

问题描述

我有一个像这样工作的应用程序。状态包含一个目标。用户可以单击保存按钮来打开文件选择器并选择目标。预期的行为是,每当用户选择目标时,应用程序都会执行保存。

下面的代码几乎可以工作。但不幸的是,当用户选择与之前状态相同的目标时,保存效果不会发生。

  const [state, dispatch] = useReducer(reducer, {
    target: "",
  });

  const setTarget = async () => {
    // user interacts with a file picker
    dispatch({ type: SET_TARGET, target});
  }

  useEffect(
    function save() {
      if (state.target) {
        // some side effects happen
      }
    },
    [state.target]
  );

使用 React 和 Hooks 的世界解决这个问题的好方法是什么?

标签: reactjsreact-hooks

解决方案


您可以使target属性的值成为一个对象,而不仅仅是一个字符串。这将起作用,因为每次更新状态时,它都会为该target属性返回一个新对象。

以下代码片段提供了一个示例:

const reducer = (state, action) => {
  switch (action.type) {
    case "SET_TARGET":
      return {
        ...state,
        target: { selectedTarget: action.payload }
      };
    default:
      return state;
  }
};

function App() {
  const [state, dispatch] = React.useReducer(reducer, {
    target: { selectedTarget: "" }
  });

  React.useEffect(() => {
    console.log("effect ran");
    console.log(state.target);
  }, [state.target]);

  const handleClick = () => {
    dispatch({ type: "SET_TARGET", payload: "New Target" });
  };

  return (
     <button onClick={handleClick}>Update Target</button>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>


推荐阅读