如何使用 react-router 在组件中保存表单的状态

Posted

技术标签:

【中文标题】如何使用 react-router 在组件中保存表单的状态【英文标题】:How do I save state of a form in a component using react-router 【发布时间】:2020-10-29 07:47:17 【问题描述】:

我有一个包含多条路线的 SPA。这些路由中的每一个都是 2 个子组件的父组件(一个表单组件和一个表格组件,显示从 API 获取的数据)。 目标是,如果用户离开它,则能够像以前一样返回到填充了字段的表单。

这是我目前所拥有的。我的index.js

ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById('root')
);

App.js

return (
            <Switch>
                <Route exact path="/" component=Landing />
                <Route path="/onDemandProductSearch" component=OnDemandProductSearch />
            </Switch>
        );

OnDemandProductSearch.js 组件有 2 个子组件,如上所述。我只显示表单,一旦选择了表单上的参数,就会显示带有获取数据的表格。

class OnDemandProductSearch extends React.Component 
    constructor(props) 
        super(props);

        this.state = 
            products: [],
            isSearched: false
        ;
    ;

    onFiltersSelected = (products, queryParams) => 
        this.setState(
            products: products,
            isSearched: true
        );
        
        this.props.history.push(
            search: queryParams
        );
    ;

    render() 
        return (
            <div>
                <Header />
                this.props.history.location.search === "" ?
                    <OnDemandProductSearchMenu onFiltersSelected=this.onFiltersSelected /> :
                    <InstanceList products=this.state.products />
            </div>
        );
    ;
;

OnDemandProductSearchMenu.js,

fetch(`$apiURL/simple-products/search`, 
            // body here
            )
        )
            .then((response) => 
                // more logic here 
            )
            .then((data) => 
                // I build a parameter string here I want the table component to be rendered with. This is important to the app
                var paramString = `.....`; 

                this.props.onFiltersSelected(data, paramString);
            )
            .catch((error) => 
                console.log(error);
            );

我阅读了 react-router 的文档,但不清楚 history 是如何工作的。我知道需要将路由推送到历史记录,但是由于表单组件无法访问history,我该如何解决?

【问题讨论】:

【参考方案1】:

有几种不同的方式可以访问历史...

您可以这样做:

    src中创建一个名为history.js的文件并将这段代码 在那里:

    import  createBrowserHistory  from 'history';
    
    export default createBrowserHistory();
    

    在您的 index.js 中导入 Router 而不是 BrowserRoouter 并使用 相反。还有import history from './history' 并将其传递为 像这样Router 的道具:

    import  Router  from 'react-router-dom'; // not BroswerRouter
    
        ReactDOM.render(
          <Router history=history>
            <App />
          </Router>,
          document.getElementById('root')
        );
    

现在,您可以随时随地访问历史记录。 只需将历史记录导入任何组件并使用 history.push()

例如在您的OnDemandProductSearch 中只需导入历史记录

import history from './history';

class OnDemandProductSearch extends React.Component 
    ......
    
    onFiltersSelected = (products, queryParams) => 
        this.setState(
            products: products,
            isSearched: true
        );
        
        history.push(
            search: queryParams
        );
    ;

    ......
;

【讨论】:

所以我知道您要我使用Router 而不是BrowserRouter 并控制history 作为道具。但是上面的代码破坏了一些东西。它不渲染任何东西。 URL 更改,但 OnDemandProductSearch 组件未显示。我尝试登录componentDidMount 网址会变成什么? 我有一个链接到OnDemandProductSearchHeader 组件。当我单击它时,路线将更改为/onDemandProductSearch(在我的App 中定义)。但是没有渲染。基本上,我看到了***.com/questions/56707885/… 中描述的问题,尽管使用了Router。我无法在应用程序中导航,但如果我直接在浏览器中输入它就会呈现。 我需要查看更多代码才能进行调试...听起来更像是结构/架构问题...如果您需要访问历史 API,我上面提到的方法是有效的这样做...... codesandbox.io/live/Q5RA7 你可以用它来查看结构。当然,我删除了一些部分,但我保留了所有我认为相关的代码

以上是关于如何使用 react-router 在组件中保存表单的状态的主要内容,如果未能解决你的问题,请参考以下文章

在 React.js 的父组件中使用 react-router 时,如何使用 react context API 将数据从父组件传递到子组件?

如何在使用react-router路由的组件中集成错误边界

如何使用链接(react-router)将道具从一个页面传递到类组件

react-router:从组件或存储更改路由

如何从文本呈现 react-router Link 组件?

如何使用React-router渲染多个组件相同的路径路径