你如何使用 React Hooks 处理外部状态?

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


class ShortestPathRenderer extends React.Component {


  ShortestPath shortestPath;


  public constructor(props) {

     this.shortestPath = new ShortestPath(props.spAlgorithm);

     this.state = { version: this.shortestPath.getVersion() };

  }


  render() {

    ... // Render waypoints from shortestPath

  }


  onComponentDidUpdate(prevProps) {

    if (prevProps.spAlgorithm !== this.props.spAlgorithm) {

      this.shortestPath.updateAlgorithm(this.props.spAlgorithm);

    }

  }


  onComponentWillUnmount() {

    this.shortestPath = undefined;

  }


  onAddWayPoint(x) {

    this.shortestPath.addWayPoint(x);

    // Check if we need to rerender

    this.setState({ version: this.shortestPath.getVersion() });

  }

}

我将如何使用 React 钩子解决这个问题?我正在考虑使用 useReducer 方法。但是,shortestPath 变量将是减速器之外的自由变量,并且减速器不再是纯的,我觉得它很脏。因此,在这种情况下,算法的整个状态必须随着算法内部状态的每次更新而被复制,并且必须返回一个新实例,这效率不高(并强制算法的逻辑为 React 方式) :


class ShortestPath {

  ... 

  addWayPoint(x) {

    // Do something

    return ShortestPath.clone(this);

  }

}


const shortestPathReducer = (state, action) => {

   switch (action.type) { 

      case ADD_WAYPOINT:

        return action.state.shortestPath.addWayPoint(action.x);

   }

}


const shortestPathRenderer = (props) => {

   const [shortestPath, dispatch] = useReducer(shortestPathReducer, new ShortestPath(props.spAlgorithm));


   return ...

}


炎炎设计
浏览 161回答 2
2回答

神不在的星期二

您可以使用 useState 钩子在功能模拟中的示例中切换基于类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]);  // ...}

慕森王

我会用这样的东西:const ShortestPathRenderer = (props) => {  const shortestPath = useMemo(() => new ShortestPath(props.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 (    ... // Render waypoints from shortestPath  )}你甚至可以进一步解耦逻辑并创建useShortestPath钩子:可重用的有状态逻辑: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  )}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript