Javascript 如何使用React钩子处理外部状态?

Javascript 如何使用React钩子处理外部状态?,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我有一个数学算法,我想把它和React分开。React将是对该算法内状态的视图,不应定义逻辑在算法内流动的方式。而且,由于它是分离的,所以对算法进行单元测试要容易得多。我已经使用类组件(简化)实现了它: 我将如何使用React钩子进行此操作?我在考虑使用useReducer方法。然而,最短路径变量将是减速器外部的自由变量,减速器不再是纯的,我发现这是脏的。因此,在这种情况下,算法的整个状态必须随着算法内部状态的每次更新而复制,并且必须返回一个新实例,这是不高效的(并迫使算法的逻辑成为反应方式):

我有一个数学算法,我想把它和React分开。React将是对该算法内状态的视图,不应定义逻辑在算法内流动的方式。而且,由于它是分离的,所以对算法进行单元测试要容易得多。我已经使用类组件(简化)实现了它:

我将如何使用React钩子进行此操作?我在考虑使用useReducer方法。然而,最短路径变量将是减速器外部的自由变量,减速器不再是纯的,我发现这是脏的。因此,在这种情况下,算法的整个状态必须随着算法内部状态的每次更新而复制,并且必须返回一个新实例,这是不高效的(并迫使算法的逻辑成为反应方式):


我会这样说:

const ShortestPathRenderer=(道具)=>{
const shortestPath=useMemo(()=>newshortestpath(props.spAlgorithm),[]);
const[version,setVersion]=useState(shortestPath.getVersion());
useffect(()=>{
最短路径更新算法(spAlgorithm);
},[spAlgorithm]);
const onAddWayPoint=(x)=>{
最短路径。添加航路点(x);
//检查我们是否需要重新招标
setVersion(shortestPath.getVersion());
}
返回(
…//从最短路径渲染航路点
)
}
您甚至可以进一步解耦逻辑并创建
useShortestPath
hook:

可重用状态逻辑:

const useShortestPath = (spAlgorithm) => {
  const shortestPath = useMemo(() => new ShortestPath(spAlgorithm), []);
  const [version, setVersion] = useState(shortestPath.getVersion());

  useEffect(() => {
     shortestPath.updateAlgorithm(spAlgorithm);
  }, [spAlgorithm]);

  const onAddWayPoint = (x) => {
    shortestPath.addWayPoint(x);
    // Check if we need to rerender
    setVersion(shortestPath.getVersion());
  }

  return [onAddWayPoint, version]
}
表现部分:

const ShortestPathRenderer = ({spAlgorithm }) => {
  const [onAddWayPoint, version] = useShortestPath(spAlgorithm);

  return (
    ... // Render waypoints from shortestPath
  )
}

只需使用useState钩子,就可以在functional analog的示例中切换类

function ShortestPathRenderer({ spAlgorithm }) {
  const [shortestPath] = useRef(new ShortestPath(spAlgorithm)); // use ref to store ShortestPath instance
  const [version, setVersion] = useState(shortestPath.current.getVersion()); // state

  const onAddWayPoint = x => {
    shortestPath.current.addWayPoint(x);
    setVersion(shortestPath.current.getVersion());
  }

  useEffect(() => {
    shortestPath.current.updateAlgorithm(spAlgorithm);
  }, [spAlgorithm]);

  // ...
}

“setMemo”会不会重新测试更新道具的最短路径?我需要保持对象的内部状态。
const ShortestPathRenderer = ({spAlgorithm }) => {
  const [onAddWayPoint, version] = useShortestPath(spAlgorithm);

  return (
    ... // Render waypoints from shortestPath
  )
}
function ShortestPathRenderer({ spAlgorithm }) {
  const [shortestPath] = useRef(new ShortestPath(spAlgorithm)); // use ref to store ShortestPath instance
  const [version, setVersion] = useState(shortestPath.current.getVersion()); // state

  const onAddWayPoint = x => {
    shortestPath.current.addWayPoint(x);
    setVersion(shortestPath.current.getVersion());
  }

  useEffect(() => {
    shortestPath.current.updateAlgorithm(spAlgorithm);
  }, [spAlgorithm]);

  // ...
}