Reactjs 如何在每次加载时在React to Redux store中保存页面名称和URL

Reactjs 如何在每次加载时在React to Redux store中保存页面名称和URL,reactjs,react-redux,Reactjs,React Redux,下面是代码更新、我的Redux应用商店中用户的pageName和pageURL,当用户浏览react应用程序时,我会得到更新 const { match } = this.props; if(match.params.type) { this.props.pageURL(match.url); this.props.pageName((match.params.type).replace(/-/g, " ")); } 如果我将此代码放在render(){方法中,一切正常,但我得到以下错

下面是代码更新、我的Redux应用商店中用户的pageName和pageURL,当用户浏览react应用程序时,我会得到更新

const { match } = this.props;
if(match.params.type) {
  this.props.pageURL(match.url);
  this.props.pageName((match.params.type).replace(/-/g, " "));
}
如果我将此代码放在
render(){
方法中,一切正常,但我得到以下错误:

Warning: Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state.
如果我把它放在类定义和渲染之间

class Skeleton extends Component {  
  render () { 
它不起作用,即使用户四处导航,存储中的页面名和URL也会保持旧

下面我将展示如何设置道具,因此我有App.js和以下代码:

<Provider store={store}>
    <BrowserRouter>
        <Fragment>
           <Route exact path="/" component={Skeleton} />  
           <Route path="/:type" component={Skeleton} />
      </Fragment>
    </BrowserRouter>
  </Provider>

尝试在渲染外部调度。具有副作用的调用应仅从componentDidMount和componentDidUpdate调用,或通过用户交互调用的任何其他方法调用。决不能在渲染内部、componentWillMount或componentWillUpdate调用

更新:

按如下方式修改组件:

// 
import React, { Component, Fragment } from 'react';
import CssBaseline from '@material-ui/core/CssBaseline';

// Parts of the page
import Sidebar from './Skeleton/Sidebar';
import Content from './Skeleton/Content';
import TopBar from './Skeleton/TopBar';

// Redux
import { connect } from 'react-redux';
import { pageName, pageURL } from './../redux/actions';

class Skeleton extends Component {  

componentDidMount() {
    const { match } = this.props;
        if(match.params.type) {
          this.props.pageURL(match.url);
          this.props.pageName((match.params.type).replace(/-/g, " "));
        }
    }

  render () { 


    return (
      <Fragment>
        <CssBaseline />
        <TopBar />
        <Sidebar /> 
        <Content />
      </Fragment>
    )
  }
}

function mapStateToProps(state) {
  return {
    pageURL,
    pageName
  }
}

const mapDispatchToProps = dispatch => {
  return {
    pageName: Name => dispatch(pageName(Name)),
    pageURL: URL => dispatch(pageURL(URL)),
  }
}

export default connect(mapStateToProps, mapDispatchToProps) (Skeleton);
//
从“React”导入React,{Component,Fragment};
从“@material ui/core/CssBaseline”导入CssBaseline;
//页面的各个部分
从“/Skeleton/Sidebar”导入侧栏;
从“/Skeleton/Content”导入内容;
从“/Skeleton/TopBar”导入TopBar;
//重演
从'react redux'导入{connect};
从“/../redux/actions”导入{pageName,pageURL};
类骨架扩展组件{
componentDidMount(){
const{match}=this.props;
if(匹配参数类型){
this.props.pageURL(match.url);
this.props.pageName((match.params.type).replace(/-/g,“”);
}
}
呈现(){
返回(
)
}
}
函数MapStateTops(状态){
返回{
页面URL,
页码
}
}
const mapDispatchToProps=调度=>{
返回{
pageName:Name=>dispatch(pageName(Name)),
pageURL:URL=>dispatch(pageURL(URL)),
}
}
导出默认连接(MapStateTrops、mapDispatchToProps)(骨架);
有一件非常重要的事情需要记住:当您分派调用时,Redux会修改组件属性,这在render()方法中是非法的

所有这样做的调用必须来自回调(如onClick等)或componentDidUpdate或componentDidMount。决不能来自componentWillUpdate或componentWillMount

从componentDidMount调用后,将从Redux更新属性,并自动触发对render()的调用。从那里,从映射中访问新的属性值


请记住,每次更改属性或状态时,React都会自动触发render(),然后触发对componentDidUpdate()的调用。因此,在componentDidUpdate中任何更新状态或属性的调用(通过Redux),在避免无限循环之前必须进行检查。

尝试调度外部渲染。具有副作用的调用只能从componentDidMount和componentDidUpdate调用,或在用户交互后调用的任何其他方法中调用。决不能在渲染内部、componentWillMount或componentWillUpdate调用

更新:

按如下方式修改组件:

// 
import React, { Component, Fragment } from 'react';
import CssBaseline from '@material-ui/core/CssBaseline';

// Parts of the page
import Sidebar from './Skeleton/Sidebar';
import Content from './Skeleton/Content';
import TopBar from './Skeleton/TopBar';

// Redux
import { connect } from 'react-redux';
import { pageName, pageURL } from './../redux/actions';

class Skeleton extends Component {  

componentDidMount() {
    const { match } = this.props;
        if(match.params.type) {
          this.props.pageURL(match.url);
          this.props.pageName((match.params.type).replace(/-/g, " "));
        }
    }

  render () { 


    return (
      <Fragment>
        <CssBaseline />
        <TopBar />
        <Sidebar /> 
        <Content />
      </Fragment>
    )
  }
}

function mapStateToProps(state) {
  return {
    pageURL,
    pageName
  }
}

const mapDispatchToProps = dispatch => {
  return {
    pageName: Name => dispatch(pageName(Name)),
    pageURL: URL => dispatch(pageURL(URL)),
  }
}

export default connect(mapStateToProps, mapDispatchToProps) (Skeleton);
//
从“React”导入React,{Component,Fragment};
从“@material ui/core/CssBaseline”导入CssBaseline;
//页面的各个部分
从“/Skeleton/Sidebar”导入侧栏;
从“/Skeleton/Content”导入内容;
从“/Skeleton/TopBar”导入TopBar;
//重演
从'react redux'导入{connect};
从“/../redux/actions”导入{pageName,pageURL};
类骨架扩展组件{
componentDidMount(){
const{match}=this.props;
if(匹配参数类型){
this.props.pageURL(match.url);
this.props.pageName((match.params.type).replace(/-/g,“”);
}
}
呈现(){
返回(
)
}
}
函数MapStateTops(状态){
返回{
页面URL,
页码
}
}
const mapDispatchToProps=调度=>{
返回{
pageName:Name=>dispatch(pageName(Name)),
pageURL:URL=>dispatch(pageURL(URL)),
}
}
导出默认连接(MapStateTrops、mapDispatchToProps)(骨架);
有一件非常重要的事情需要记住:当您分派调用时,Redux会修改组件属性,这在render()方法中是非法的

所有这样做的调用必须来自回调(如onClick等)或componentDidUpdate或componentDidMount。决不能来自componentWillUpdate或componentWillMount

从componentDidMount调用后,将从Redux更新属性,并自动触发对render()的调用。从那里,从映射中访问新的属性值


请记住,每次更改属性或状态时,React都会自动触发render(),然后触发对componentDidUpdate()的调用。因此,在componentDidUpdate中任何更新状态或属性的调用(通过Redux),在避免无限循环之前必须进行检查。

正如错误所述,您不应该在渲染期间更新状态,实现这一点的方法是在调用函数以避免渲染无限循环之前检查您的状态/属性更改。尝试以下方法:

componentDidUpdate(prevProps) {
  const {
    match: { url, params },
    pageName,
    pageUrl
  } = this.props

  // Typical usage (don't forget to compare props)
  if (url !== prevProps.match.url) {
    pageUrl(url)
    pageName((params.type).replace(/-/g, " "));
  }
}

componentDidMount() {
  const {
    match: { url, params },
    pageName,
    pageUrl
  } = this.props

  pageUrl(url)
  pageName((params.type).replace(/-/g, " "));
}

正如错误所说,不应该在渲染期间更新状态,实现这一点的方法是在调用函数之前检查状态/属性更改,以避免渲染无限循环。请尝试以下操作:

componentDidUpdate(prevProps) {
  const {
    match: { url, params },
    pageName,
    pageUrl
  } = this.props

  // Typical usage (don't forget to compare props)
  if (url !== prevProps.match.url) {
    pageUrl(url)
    pageName((params.type).replace(/-/g, " "));
  }
}

componentDidMount() {
  const {
    match: { url, params },
    pageName,
    pageUrl
  } = this.props

  pageUrl(url)
  pageName((params.type).replace(/-/g, " "));
}

你能给我们看一下pageURL和pageName道具的代码吗?还有为什么这些函数作为道具传递,而不是作为此组件中的一个方法?@Lelouch谢谢,我刚刚更新了它。你能给我们看一下pageURL和pageName道具的代码吗?还有为什么这些函数作为道具传递,而不是作为此组件中的一个方法?@Lelouch谢谢你,我刚刚更新了它。我尝试了你提到的所有生命周期挂钩,没有一个能正常工作。你仍然收到相同的错误消息吗?你介意发布整个组件代码吗?当然,刚刚添加了。请参阅我修改的答案。你从原始帖子中收到错误消息吗?如果这是固定的,则