简体   繁体   English

从未加载 react-router-dom 的组件中使用 state

[英]Using state from components not loaded with react-router-dom

I re-formatted the question with an example using the star wars API.我使用星球大战 API 的示例重新格式化了问题。 The problem I am having is trying to use state from PeoplePage and passing to the CounterPage while using react-router-dom.我遇到的问题是尝试使用 PeoplePage 中的 state 并在使用 react-router-dom 时传递给 CounterPage。 This is a small example of my real website.这是我真实网站的一个小例子。 I am trying to narrow down the actual issue with this example.我试图用这个例子缩小实际问题的范围。 I hope this clarifies what I am working to achieve.我希望这能澄清我正在努力实现的目标。 Thanks!谢谢!

import React from 'react';
import {BrowserRouter as Router,Switch,Route} from 'react-router-dom';

class ExampleApp extends React.Component{
    constructor(){
        super()
        this.state = {
            starWarsPeople:[],
            stateNumber:0
        }
    }
    numberHandler(number){
        console.log('number',number)
        this.setState({stateNumber: this.state.stateNumber + number})
    }
    componentDidMount(){
        fetch('https://swapi.dev/api/people')
        .then(response => response.json())
        .then(data =>this.setState({starWarsPeople:data}))

    }
    render(){
        const {starWarsPeople,stateNumber} = this.state
        console.log(stateNumber);
        return(
            <Router>
                <div>
                    <Switch>
        /* Issue----->*/ <Route path ='/people' exact render = /*Render is where I am stuck */
                            {starWarsPeople.length !==0
                                ?
                                <PeoplePage prop1 = {starWarsPeople} increment ={this.numberHandler.bind(this)}/>
                                :
                                <div>loading...</div>
                            }
                        />
        /* Issue----->*/ <Route path ='/counter' exact render = 
                        /*render is where I am stuck, interval will not go to count prop when this is loaded*/
                            {starWarsPeople.length !==0
                                ?
                                /*this example will render but not sure if its right and the interval will not work:
                                <Route path ='/counter' exact render = {
                                (props)=><CounterPage {...props} people ={starWarsPeople} key = {stateNumber}/>}/> */
                                <CounterPage people ={starWarsPeople} key = {stateNumber}/*I want this to re-render every time the inverval changes *//>
                                :
                                <div>loading...</div>
                            }
                        />
                    </Switch>
                </div>
            </Router>
        )
    }
}
export default ExampleApp;


class PeoplePage extends React.Component {
    constructor(props){
        super(props)
        this.state ={
            number:0
        }
    }
    componentDidMount(){
        this.myInterval = setInterval(()=>{
            this.setState({state:this.state+1})
            this.props.increment(1);
        },1000)
    }
    componentWillUnmount(){
        clearInterval(this.myInterval);
    }
    render(){
    return(
        <div>
            {this.props.prop1.results[0].name}
        </div>
    )
    }
}

const CounterPage =({count})=>{
    return(
        <div>{count}</div>
    )
}

I'm not entirely sure what your app code is supposed to be doing, but when I copy/pasted your code snippets into a codesandbox there were a few issues I had to address before the code would run.我不完全确定您的应用程序代码应该做什么,但是当我将您的代码片段复制/粘贴到代码沙箱中时,在代码运行之前我必须解决一些问题。

Issues问题

  1. Each Route 's render prop wasn't returning a render function.每个Routerender道具没有返回渲染 function。
  2. Each Route 's path prop wasn't an absolute path.每个Routepath道具都不是绝对路径。
  3. PeoplePage 's state update was incorrectly updating its state. PeoplePage的 state 更新错误地更新了其 state。 Doesn't access the correct previous state, ie state isn't a number so this.state + 1 won't work.不访问正确的以前的 state,即 state 不是数字,所以this.state + 1不起作用。
  4. CounterPage consumes and renders only a count prop, but isn't passed this prop. CounterPage只消耗和渲染一个count道具,但没有传递这个道具。

Fixes修复

Routes路线

<Route
  path="/people" // <-- fix path
  exact
  render={(routeProps) => // <-- use a render function to return UI
    starWarsPeople.length !== 0 ? (
      <PeoplePage
        prop1={starWarsPeople}
        increment={this.numberHandler.bind(this)}
        {...routeProps} // <-- pass on route props
      />
    ) : (
      <div>loading...</div>
    )
  }
/>
<Route
  path="/counter" // <-- fix path
  exact
  render ={(routeProps) => // <-- use a render function to return UI
    starWarsPeople.length !== 0 ? (
      <CounterPage
        people={starWarsPeople}
        count={stateNumber} // <-- pass count prop
        key={stateNumber}
        {...routeProps} // <-- pass on route props
      />
    ) : (
      <div>loading...</div>
    )
  }
/>

PeoplePage人物页面

class PeoplePage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      number: 0
    };
  }
  componentDidMount() {
    this.myInterval = setInterval(() => {
      this.setState(({ number }) => ({ number: number + 1 }));
      this.props.increment(1);
    }, 1000);
  }
  componentWillUnmount() {
    clearInterval(this.myInterval);
  }
  render() {
    return <div>{this.props.prop1.results[0].name}</div>;
  }
}

编辑 using-state-from-components-not-loaded-with-react-router-dom

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM