【问题标题】:How to pass `props` data from parent to child on react router如何在反应路由器上将`props`数据从父母传递给孩子
【发布时间】:2019-07-20 15:45:20
【问题描述】:

当我的props 数据将路由到新路径时,我想将其从父级传递给子级。 我尝试了一些https://github.com/ReactTraining/react-router/issues/4105,但当我通过{...props} 传递它时实际上并没有工作。

任何帮助都会非常有用。

//App.js

class App extends Component{
  constructor(props){
    super(props);
  }

  render(){
    return (
      <div className="App">
        <div className="navbar">
          <h2 className="center">Tiny Book Library</h2>
        </div>
        <Switch>
          <Route exact path="/" component={PostBook}/>
          <Route exact path="/abc" render={props => <AllBook someProp="2" {...props} />} />
        </Switch>

      </div>
    );
  }
}

//Allbook.js

class AllBook extends Component {
    constructor(props){
        super(props);
      }
    render(){
        return(
            <div>
                {Object.keys(this.props.posts).length !== 0 ?  <h1 className="post-heading">All books</h1> : ""}  {/*To check if array is empty or not*/}

                {/*Arrow function to map each added object*/}
                {this.props.posts.map((post) =>(

                    <div key={post.id}>

                        {post.editing ? <EditComponent post={post} key={post.id}/> :
                            <Post key={post.id} post={post}/>}
                    </div>
                ))}
            </div>
        );
    }
}

const mapStateToProps = (state) => {
    return{
        posts: state
    }
}
export default connect(mapStateToProps)(AllBook);

//减速器

const postReducer = (state = [], action) => {
    switch(action.type){
        case 'ADD_BOOK':
            return state.concat([action.data]);
        case 'DELETE_BOOK':
            return state.filter((post) => post.id !== action.id);
        case 'EDIT_BOOK':
            return state.map((post)=>post.id === action.id ? {...post, editing:!post.editing} : post)
        case 'UPDATE':
            return state.map((post)=>{
                if(post.id === action.id){
                    return{
                        ...post,
                        title: action.data.newTitle,
                        number:action.data.newNumber,
                        author:action.data.newAuthor,
                        description:action.data.newDescription,
                        editing: !post.editing
                    }
                } 
                else return post;
            })
        default:
            return state;
    }
}
export default postReducer;

【问题讨论】:

  • 父母的哪个道具在从父母传递给孩子时遇到问题?如果是帖子,那么如果您从 Redux 商店获取帖子,我将不得不问为什么要通过帖子。如果不是,那就是另一个问题了。
  • @AlexanderStaroselsky 是的,来自postbook 我想把它传递给allBook,这样我所有的书都可以在那里看到。但是在更改为路由器props 时,数据不存储任何值。
  • @AlexanderStaroselsky 是的,我从redux 商店获得posts。那我需要改变什么?
  • 请问您为什么不将 AllBook 连接到 redux,以便在准备好时接收帖子列表?
  • @AdolfoOnrubia 嗯不确定。你认为我需要在这里改变什么?我已经更新了我的代码。

标签: javascript reactjs react-router react-props


【解决方案1】:

更新 #1:添加 链接 以实现正确的页面转换:

  • 首先:importLink 组件位于 App.js 的开头:

import { Link } from 'react-router-dom'

  • 第二:添加Link组件在两个页面之间进行路由:
class App extends Component{
  constructor(props){
    super(props);
  }

  render(){
    return (
      <div className="App">
        <div className="navbar">
          <h2 className="center">Tiny Book Library</h2>
          <Link to="/">Post A Book</Link>
          <Link to="/abc">All Books</Link>
        </div>
        <Switch>
          <Route exact path="/" component={PostBook}/>
          <Route exact path="/abc" render={props => <AllBook someProp="2" {...props} />} />
        </Switch>

      </div>
    );
  }
}

上面的代码可能没有什么问题,导致这种行为的原因是从浏览器手动更改路由。

导致问题的原因。

进一步解释:

  • 您将表单中的数据发布在 PostBook 中。
  • 数据存储在reducer中。
  • 您从浏览器手动更改 url,您会丢失您提交给 reducer 的所有数据,这不是错误,也不是预期行为,因为这样做会请求全新的应用因此,为您提供零数据。

请阅读Link,以正确更改网址,以便您可以测试您的代码是否有效。

【讨论】:

  • 这里有一个很好的 reference 供您讨论单页应用程序中的路由。
【解决方案2】:

正如react-routerdocs 中提到的,render 函数道具中的参数是路由器道具:即Route 组件通常会得到的道具:historylocation 等.

你不想这样,你想传递你自己/父母的道具: \App.js

class App extends Component{
  constructor(props){
    super(props);
  }

  render(){
    const myProps = this.props;

    return (
      <div className="App">
        <div className="navbar">
          <h2 className="center">Tiny Book Library</h2>
        </div>
        <Switch>
          <Route exact path="/" component={PostBook}/>
          <Route exact path="/abc" render={() => <AllBook someProp="2" {...myProps} />} />
        </Switch>

      </div>
    );
  }
}

【讨论】:

    【解决方案3】:

    不确定是否会有所帮助。 订阅 Allbook 到帖子,在您的情况下,您的整个 redux 商店看起来只是帖子,或者至少您将所有 redux 状态传递给 posts

    class AllBook extends Component {
        constructor(props){
            super(props);
          }
        render(){
            return(
                <div>
                    {Object.keys(this.props.posts).length !== 0 ?  <h1 className="post-heading">All books</h1> : ""}  {/*To check if array is empty or not*/}
    
                    {/*Arrow function to map each added object*/}
                    {this.props.posts.map((post) =>(
    
                        <div key={post.id}>
    
                            {post.editing ? <EditComponent post={post} key={post.id}/> :
                                <Post key={post.id} post={post}/>}
                        </div>
                    ))}
                </div>
            );
        }
    }
    
    // (state) => { return { posts: state.posts } }; Should also work.
    const mapStateToProps = ({ posts }) => ({ posts });
    
    export default connect(mapStateToProps)(AllBook);
    

    【讨论】:

      猜你喜欢
      • 2020-04-29
      • 2022-09-26
      • 2020-09-19
      • 2020-04-06
      • 2021-10-31
      • 2020-10-31
      • 2021-10-16
      • 1970-01-01
      • 2022-11-21
      相关资源
      最近更新 更多