使用 props 将 Redux Action 传递给子组件

Posted

技术标签:

【中文标题】使用 props 将 Redux Action 传递给子组件【英文标题】:Passing a Redux Action to a child component with props 【发布时间】:2016-07-15 02:37:30 【问题描述】:

当用户点击某个项目时,我正在尝试将我的应用中的视频设置为“精选”。我有一个动作创建器,它在调用时执行一个简单的 console.log(),为了测试,我将它称为 w/componentDidMount(),它工作正常。我有一个用于 VideoItem 的单独组件,我正在尝试传递动作创建者,但我收到一个错误:TypeError: Cannot read property 'props' of undefined。我尝试将.bind(this) 添加到我传递的操作的末尾,但没有任何作用。

如果我在componentDidMount 调用它时动作创建器有效,为什么我不能将它传递给子组件?这是我的 Video 和 VideoItem 组件:

// Video.js


import React,  Component  from 'react'
import VideoItem from './VideoItem'
class Videos extends Component 
  componentDidMount() 
      this.props.actions.getVideos()
      // This function works, but getting error
      // when passing to VideoItem component
      this.props.actions.setFeaturedVideo()
  
  constructor(props) 
      super(props);
  
  render() 
    if(this.props.videos.length == 0)
      return <p>Loading....</p>
    
    return (
        <div className="container">
          <ul className="row">
              this.props.videos.map(function(result) 
                return (
                    <VideoItem
                    key=result.position
                    setFeaturedVideo=this.props.setFeaturedVideo
                    video=result

                    />
                )
              )
          </ul>
        </div>
    )
  


export default Videos


// VideoItem.js

import React,  Component  from 'react'
class VideoItem extends Component 
  constructor(props) 
      super(props);
  
  render() 
    return (
      <li className="col m6" onClick=this.props.setFeaturedVideo()>
          this.props.video.title
      </li>

    )
  

export default VideoItem

【问题讨论】:

如果将 props 记录到 componentWillReceiveProps 会发生什么? 【参考方案1】:

我注意到对于 VideoItem 组件,您的代码像这样传递函数

<VideoItem
  key=result.position
  setFeaturedVideo=this.props.setFeaturedVideo
  video=result
/>

但是在你的componentDidMount 中你调用this.props.actions.setFeatureVideo()

所以对我来说,你没有将函数作为道具传递,因为你试图从 this.props 而不是 this.props.actions 获取它

【讨论】:

【参考方案2】:

在地图函数中错过了这个。由于您使用的是地图,因此“this”属于地图功能。您需要在 map 函数之前将其分配给一个变量并使用它。

render() 
    var _that = this;
    if(this.props.videos.length == 0)
      return <p>Loading....</p>
    
return (
    <div className="container">
      <ul className="row">
          this.props.videos.map(function(result) 
            return (
                <VideoIte
                key=result.position
                setFeaturedVideo=_that.props.actions.setFeaturedVideo
                video=result

                />
            )
          )
      </ul>
    </div>
)

【讨论】:

感谢 Norm 的快速回复,当我进行更改时,我仍然收到 Videos.js:25 Uncaught TypeError: Cannot read property 'props' of undefined 错误 我已经更新了我的答案。我错过了您在地图功能中的事实。您需要将“this”映射到 return 之外的变量,以便您可以在 map 函数中访问它。 Norm 也说出了我所了解的内容,并且应该是这样的。顺便说一句,看起来您正在使用 ES6。你可以解构你的道具,这样你就不必做像_that 这样的事情。相反,您可以在 render 方法的顶部使用 const actions, videos = this.props。然后,无论你在哪里使用过this.props.*,都可以直接调用它。例如,videos.map(result =&gt; &lt;VideoItem key=result.position setFeaturedVideo=actions.setFeaturedVideo video=result) 另一个附加说明 - 因为您使用的是 Redux(我假设基于操作),而不是检查 videos.length === 0,您可以将 isLoading 作为状态的一部分- 然后在加载内容时,您发送一个操作以将 isLoading 从 true 更新为 false 并相应地重新流动。

以上是关于使用 props 将 Redux Action 传递给子组件的主要内容,如果未能解决你的问题,请参考以下文章

React Native Redux:动作分派,返回结果

mapDispatchToProps 不工作。 props 为空(错误:redux action 不是函数)

关于react-redux的mapStateToProps取到值(state会更新变化)但不会注入props的问题

使用 React/Redux saga 将数据从组件传递到 action 和 saga

等待带有 React Hooks 的 Redux Action

在 useEffect 中调用 Redux Action