Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 重定向上的React导航组件在刷新时丢失数据_Reactjs - Fatal编程技术网

Reactjs 重定向上的React导航组件在刷新时丢失数据

Reactjs 重定向上的React导航组件在刷新时丢失数据,reactjs,Reactjs,我使用的是React 16.4.1和React路由器Dom 4.3.1。我已经使用一个web组件构建了一个侧栏react组件,您可以将数据传递到web组件中,这将呈现该组件 import React from 'react'; import PropTypes from 'prop-types'; import ReactDOM from 'react-dom'; import { Redirect } from 'react-router-dom'; class Sidebar extend

我使用的是React 16.4.1和React路由器Dom 4.3.1。我已经使用一个web组件构建了一个侧栏react组件,您可以将数据传递到web组件中,这将呈现该组件

import React from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import { Redirect } from 'react-router-dom';

class Sidebar extends React.Component {
    constructor(props, context) {
      super(props, context);
      this.mySideBarRef = React.createRef();
      this.menuClick = this.menuClick.bind(this);

      this.state = {
        redirect: false,
        redirectUrl: '/',
        menuData: [
          {
            groupName: 'Group 1',
            icon: 'Home',
            children: [
              {
                title: 'Home',
                icon: 'favorite',
                url: '/',
              },
              {
                title: 'Grp 1 Item 2',
                children: [
                {
                title: 'Roles',
                icon: 'Person',
                url: '/roles',
              },
              {
                title: 'About',
                icon: 'gesture',
                url: '/about',
              },
                  {
                    title: 'Google',
                    icon: 'world',
                    url: 'http://www.google.co.uk',
                  },
                ],
              },
            ],
          },
          {
            groupName: 'Group 2',
            icon: 'search',
            children: [
              {
                title: 'Grp 2 Item 1',
                icon: 'microsoft',
                children: [
                  {
                    title: 'Grp 2 Item 1.1 Bing',
                    icon: '',
                    url: 'http://www.google.co.uk',
                  },
                  {
                    title: 'Grp 2 Item 1.2 Bing',
                    icon: '',
                    url: 'http://www.bing.com',
                  },
                ],
              },
            ],
          },
        ],
      };
    }

    componentDidMount() {
      let sideMenuContainer = this.mySideBarRef.current;
      sideMenuContainer.sideMenuData = this.state.menuData;
      sideMenuContainer.overrideCustomUrlEvent = true;
      window.addEventListener('customUrlEvent', this.menuClick)
    }

    menuClick(e) {
      console.log(e);
      this.setState({
          redirect: true,
          redirectUrl: e.url
      });
    }

    componentWillUnmount() {
      this.mySideBarRef.current.removeEventListener('customUrlEvent', this.menuClick);

    }

    render() {
      if(this.state.redirect) {
        this.state.redirect = false;
        return <Redirect to={this.state.redirectUrl} />;
      }


      if(this.state.menuData !== null) {
        return(
          <side-bar-component 
            ref={this.mySideBarRef}
            collapsable>
          </side-bar-component>
        );
      }
    }
  }

export default Sidebar;
这是侧杆组件

import React from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import { Redirect } from 'react-router-dom';

class Sidebar extends React.Component {
    constructor(props, context) {
      super(props, context);
      this.mySideBarRef = React.createRef();
      this.menuClick = this.menuClick.bind(this);

      this.state = {
        redirect: false,
        redirectUrl: '/',
        menuData: [
          {
            groupName: 'Group 1',
            icon: 'Home',
            children: [
              {
                title: 'Home',
                icon: 'favorite',
                url: '/',
              },
              {
                title: 'Grp 1 Item 2',
                children: [
                {
                title: 'Roles',
                icon: 'Person',
                url: '/roles',
              },
              {
                title: 'About',
                icon: 'gesture',
                url: '/about',
              },
                  {
                    title: 'Google',
                    icon: 'world',
                    url: 'http://www.google.co.uk',
                  },
                ],
              },
            ],
          },
          {
            groupName: 'Group 2',
            icon: 'search',
            children: [
              {
                title: 'Grp 2 Item 1',
                icon: 'microsoft',
                children: [
                  {
                    title: 'Grp 2 Item 1.1 Bing',
                    icon: '',
                    url: 'http://www.google.co.uk',
                  },
                  {
                    title: 'Grp 2 Item 1.2 Bing',
                    icon: '',
                    url: 'http://www.bing.com',
                  },
                ],
              },
            ],
          },
        ],
      };
    }

    componentDidMount() {
      let sideMenuContainer = this.mySideBarRef.current;
      sideMenuContainer.sideMenuData = this.state.menuData;
      sideMenuContainer.overrideCustomUrlEvent = true;
      window.addEventListener('customUrlEvent', this.menuClick)
    }

    menuClick(e) {
      console.log(e);
      this.setState({
          redirect: true,
          redirectUrl: e.url
      });
    }

    componentWillUnmount() {
      this.mySideBarRef.current.removeEventListener('customUrlEvent', this.menuClick);

    }

    render() {
      if(this.state.redirect) {
        this.state.redirect = false;
        return <Redirect to={this.state.redirectUrl} />;
      }


      if(this.state.menuData !== null) {
        return(
          <side-bar-component 
            ref={this.mySideBarRef}
            collapsable>
          </side-bar-component>
        );
      }
    }
  }

export default Sidebar;
**

很抱歉我反应迟钝,但我期待你的回答 帮助再次感谢你们的支持

**

还包括my routes.js,以防可能需要它来帮助解决此问题

import React from 'react';
import { Route, IndexRoute, Switch } from 'react-router-dom';
// import { Route, IndexRoute  } from 'react-router';
import App from './components/app';
import HomePage from './components/home/home-page';
import AboutPage from './components/about/about-page';
import RolesPage from './components/role/roles-page';
import ManageRolePage from './components/role/manage-role-page'; //eslint-disable-line import/no-named-as-default

export default (
  <Switch>
    <Route path="/" components={App}>
      <IndexRoute component={HomePage} />
      <Route path="roles" component={RolesPage}/>
      <Route path="role" component={ManageRolePage}/>
      <Route path="role/:id" component={ManageRolePage}/>
      <Route path="about" component={AboutPage}/>
    </Route>
  </Switch>
);

这意味着状态没有被更新,但我可以保留菜单展开,但页面不会重定向,因为我没有点击渲染函数事件。

组件将在其状态或道具更改时重新渲染,这意味着它们的
渲染
方法将再次运行,以及它们的相关生命周期方法

关于您的代码,我注意到最多的是您正在使用
路由
,但您没有使用
交换机
浏览器路由器
。这可能是相关的。我不能确定,但因为您的
组件位于路由的上游,除非其状态或道具发生更改,否则它将不会重新渲染或更新

我认为你的边栏不会更新,数据可能会在最初加载,但会变得陈旧

但不要害怕,请允许我给你链接一篇文章,我认为这篇文章将把你带到下一个层次:(给未来的个人注意:如果这个URL在未来中断,请让我知道)

我想你读了之后会明白的,但它会详细说明
浏览器路由器
交换机
,以及
路由
。我认为你需要改变你的代码来使用这三个

请记住,侧边栏(及其所有子项)只有在其状态或道具发生更改时才会更新

你可以这样做:

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      data: {},
    }
  }
  render() {
    return (
      <div>
        <Sidebar data={this.state.data} />
        <AnotherComponent onEventOccurred={newData => this.setState({ data: newData })} />
      </div>
    )
  }
}
该组件有一个名为
oneventoccured
的属性,可以从该组件内部调用该属性作为
this.props.oneventoccured(newData)
,或者如果功能性非类组件作为
props.oneventoccured()
。它实际上只是一个回调,所以你调用它,它在其父级中激发
this.setState()
。这是一个非常强大的模式,因为它允许父级控制它将为该事件执行的操作,因为操作是在父级中定义的。子对象只是触发回调

起初我很犹豫是否要发布一个答案,但现在我觉得你可能会从中受益匪浅。如果还不清楚具体情况,请告诉我。我想让你先看看我链接的那篇媒体文章。其中显示的模式非常常见且惯用

我刚注意到你安装了Redux。总的来说,这确实增加了复杂性,但对于跨领域的关注点来说是好的。有时我们称之为横向数据加载。通常,React中的数据是单向流动的,这意味着总是从父级到子级,从上游到下游

使用Redux,您可以从任何组件调用动作创建者,并且边栏将监听状态对象上的更改。当您希望在多个未直接连接的组件之间共享状态片段时,可以使用Redux

使用Redux,连接的组件将侦听“基本”全局状态树上的更改。当状态更改时,订阅的组件将更新

例如,在侧边栏中,可以有以下内容:

function mapStateToProps(state, ownProps) {
  return {
    loading: state.ajaxCallsInProgress > 0,
    data: state.sidebar,
  };
}
每次更改
state.sidebar
时,它都会更新其
this.props.data
。我尽量把这件事保持在最低限度,因为我可能会用额外的信息把你搞糊涂,但这是最重要的部分。使用
connect()
的组件订阅全局状态树上的更改


Connect是一个高阶组件,它使用该组件包装组件,因此当应用程序的状态发生变化时,它会导致该组件的道具发生变化,从而触发重新渲染。

嗨,Adam,首先感谢您的回复。你的建议很好,谢谢你。我正在尝试你推荐的几种方法,并将反馈我是如何做到这一点的。鲍比,我看到你编辑了我的答案,结果被拒绝了。试着把同样的东西贴到问题的底部。堆栈溢出不是做这种增量插件类型事情的最佳方式。如果您丢失了更改,我仍然可以在被拒绝的评论中看到它们。让我知道,我会更仔细地检查它们,但最好的补充是在你的问题中,比如:“基于以下答案的新内容”。幸运的是,我没有关闭我的机器,因此能够进入浏览器历史记录以获取此信息。:)没有完全解决我的问题,但为我指明了正确的方向。
if(this.state.sideMenu.menuData !== undefined) {
  sideMenuContainer.sideMenuData = this.state.sideMenu.menuData;
}
import React from 'react';
import { Route, IndexRoute, Switch } from 'react-router-dom';
// import { Route, IndexRoute  } from 'react-router';
import App from './components/app';
import HomePage from './components/home/home-page';
import AboutPage from './components/about/about-page';
import RolesPage from './components/role/roles-page';
import ManageRolePage from './components/role/manage-role-page'; //eslint-disable-line import/no-named-as-default

export default (
  <Switch>
    <Route path="/" components={App}>
      <IndexRoute component={HomePage} />
      <Route path="roles" component={RolesPage}/>
      <Route path="role" component={ManageRolePage}/>
      <Route path="role/:id" component={ManageRolePage}/>
      <Route path="about" component={AboutPage}/>
    </Route>
  </Switch>
);
menuClick(e) {
    console.log(e);
    this.redirectUrl = e.url;
    this.redirect = true;
  }
class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      data: {},
    }
  }
  render() {
    return (
      <div>
        <Sidebar data={this.state.data} />
        <AnotherComponent onEventOccurred={newData => this.setState({ data: newData })} />
      </div>
    )
  }
}
<AnotherComponent onEventOccurred={newData => this.setState({ data: newData })} />
function mapStateToProps(state, ownProps) {
  return {
    loading: state.ajaxCallsInProgress > 0,
    data: state.sidebar,
  };
}