如何避免在具有动态重定向的组件中进行不必要的重新安装?

问题描述

在我的应用中,我尝试使用 useReducer useContext react-router来实现步进器(内部带有表单) -dom 。 此处的示例正在我的应用程序中紧密模拟代码:Codesandbox

因此,我有一个Parent组件,该组件从config动态绘制路由,并重定向到当前活动的步骤:

配置

const config = [
  {
    path: "one",label: "Step One",component: Child
  },{
    path: "two",label: "Step Two",{
    path: "three",label: "Step Three",component: Child
  }
];

Parent.js

export default function Parent({ steps }) {
  const [state,dispatch] = useContextReducer(); // see Codesandbox
  const { path } = useRouteMatch();
  const { id } = useParams();
  const onClick = useCallback(() => {
    dispatch({ type: "RESET" });
  },[dispatch]);

  useEffect(() => {
    console.log("PARENT RENDERED");
    // constantly being triggered,both on initial redirect and also on every 
    //  change in children (see example)
    return () => console.log("PARENT UNMOUNTED");
  });

  return (
    <>
      <p>Current step: {steps[state.activeStep].label}</p>
      <button type="button" onClick={onClick}>
        Reset
      </button>
      <p></p>
      <Switch>
        {steps.map(({ path: pathName,component: Component }) => (
          <Route
            key="1"
            path={`${path}/${pathName}`}
            render={(routeProps) => (
              <Component {...routeProps} id={id}></Component>
            )}
          ></Route>
        ))}
      </Switch>
      <Route
        path={path}
        render={({ match }) => (
          <Redirect to={`${match.url}/${steps[state.activeStep].path}`} />
        )}
      ></Route>
    </>
  );
}

Child.js

export default function Child({ id }) {
  const [state,dispatch] = useContextReducer(); // see Codesandbox
  const onNext = useCallback(
    function () {
      dispatch({ type: "NEXT" });
    },[dispatch]
  );

  const onBack = useCallback(
    function () {
      dispatch({ type: "BACK" });
    },[dispatch]
  );

  return (
    <div>
      <button disabled={state.activeStep === 0} type="button" onClick={onBack}>
        Back {id}
      </button>
      <button
        disabled={state.steps.length - 1 === state.activeStep}
        type="button"
        onClick={onNext}
      >
        Next {id}
      </button>
    </div>
  );
}

父母的包装

function IntermediaryRoute() {
  return (
    <ContextReducerProvider init={init}>
      <Parent steps={config}></Parent>
    </ContextReducerProvider>
  );
}

这里的问题是,父子组件在子组件中的每次更改时都被重新安装并重新呈现。可能是因为父级使用上下文,而上下文在子级中每次单击按钮时都会更改。 但这也可能是因为其中包含动态重定向。

我可能应该在其他组件中具有隔离状态和Context Provider,但是无论如何它都应该重新安装。因为Parent仍然必须使用状态来动态呈现路由并动态重定向到当前活动步骤。

我现在不知道如何在不重新渲染父级或至少不重新安装父级的情况下实现该功能。

在我的应用程序中的一个Child中,我有一个很重的表,可以从api加载数据。在离开并进入“父组件”的某个时刻,应用程序挂断并死掉,没有任何错误。

我猜想是因为母组件不断地重新安装-您可以在Codesandbox中看到它。

任何有关实现这种步进器的帮助或技巧都将受到赞赏。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...