为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

炎炎设计 2021-11-18 20:10:47
我有一个数学算法,我想与 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 ...}
查看完整描述

2 回答

?
神不在的星期二

TA贡献1963条经验 获得超6个赞

您可以使用 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]);


  // ...

}


查看完整回答
反对 回复 2021-11-18
?
慕森王

TA贡献1777条经验 获得超3个赞

我会用这样的东西:


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

  )

}


查看完整回答
反对 回复 2021-11-18
  • 2 回答
  • 0 关注
  • 160 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信