Reactjs 最后一个子组件覆盖所有子组件

Reactjs 最后一个子组件覆盖所有子组件,reactjs,redux,react-redux,Reactjs,Redux,React Redux,我有一个包含3个子项的父组件: <ChildComponent category="foo" /> <ChildComponent category="bar" /> <ChildComponent category="baz" /> 在我的操作中,数据按预期返回。但是,当子组件呈现数据时。最后一个子baz也在覆盖foo和bar中的值 A。但我希望这是动态的,只取决于类别道具。在Redux中不可能这样做吗 我的子组件如下所示: class TweetColu

我有一个包含3个子项的父组件:

<ChildComponent category="foo" />
<ChildComponent category="bar" />
<ChildComponent category="baz" />
在我的操作中,数据按预期返回。但是,当子组件呈现数据时。最后一个子baz也在覆盖foo和bar中的值

A。但我希望这是动态的,只取决于类别道具。在Redux中不可能这样做吗

我的子组件如下所示:

class TweetColumn extends Component {

  componentDidMount() {
    this.props.fetchTweets(this.props.column)
  }

  render() {
    const { tweets, column } = this.props
    if (tweets.length === 0) { return null }
    const tweetItems = tweets[column].map(tweet => (
      <div key={ tweet.id }>
        { tweetItems.name }
      </div>
    )
    return (
      <div className="box-content">
        { tweetItems }
      </div>
    )
  }
}

TweetColumn.propTypes = {
  fetchTweets: PropTypes.func.isRequired,
  tweets: PropTypes.array.isRequired
}

const mapStateToProps = state => ({
  tweets: state.tweets.items
})

export default connect(mapStateToProps, { fetchTweets })( TweetColumn )
行动:

export const fetchTweets = (column) => dispatch => {
  dispatch({ type: FETCH_TWEETS_START })
  const url = `${ TWITTER_API }/statuses/user_timeline.json?count=30&screen_name=${ column }`
  return axios.get(url)
    .then(response => dispatch({
      type: FETCH_TWEETS_SUCCESS,
      data: response.data
    }))
    .then(response => console.log(response.data))
    .catch(e => dispatch({type: FETCH_TWEETS_FAIL}))

}

每次装入
TweetColumn
时,您都在进行api调用。如果您有多个
TweetColumn
组件,并且每个组件都进行api调用,那么最后到达的响应将设置
state.tweets.items
的值。这是因为您每次都发送相同的操作
FETCH\u TWEETS\u SUCCESS
(最后一个操作覆盖前一个操作)。为了解决这个问题,假设响应有一个
类别
(foo,bar,baz),我将用以下方式编写reducer:

export default function tweetReducer(state = initialState, action) {
  switch (action.type) {
    case FETCH_TWEETS_SUCCESS:
      return {
          ...state,
          [action.data.category]: action.data
      }
    default:
      return state;
  }
}
然后,您可以在
tweet列中执行以下操作:

class TweetColumn extends Component {

  componentDidMount() {
    this.props.fetchTweets(this.props.column)
  }

  render() {
    const { column } = this.props;
    const tweetItems = this.props.tweets[column].map(tweet => (
      <div key={ tweet.id }>
        { tweet.name }
      </div>
    )
    return (
      <div className="box-content">
        { tweetItems }
      </div>
    )
  }
}

const mapStateToProps = state => ({
  tweets: state.tweets
})

const mapDispatchToProps = dispatch => ({
  fetchTweets: column => dispatch(fetchTweets(column))
})

export default connect(
  mapStateToProps,
  mapDispatchToProps,
)( TweetColumn )
类TweetColumn扩展组件{
componentDidMount(){
this.props.fetchTweets(this.props.column)
}
render(){
const{column}=this.props;
const tweetItems=this.props.tweets[column].map(tweet=>(
{tweet.name}
)
返回(
{tweetItems}
)
}
}
常量mapStateToProps=状态=>({
tweets:state.tweets
})
const mapDispatchToProps=调度=>({
fetchTweets:column=>dispatch(fetchTweets(column))
})
导出默认连接(
MapStateTops,
mapDispatchToProps,
)(推特专栏)

您必须进行一些验证,以确保
tweets[列]
存在,但你明白了。

每次安装
TweetColumn
时,你都在进行api调用。如果你有多个
TweetColumn
组件,并且每个组件都进行api调用,那么最后到达的响应都将设置
state.tweets.items
的值。这是因为你在调度每次执行相同的操作
FETCH\u TWEETS\u SUCCESS
(最后一个操作会覆盖上一个操作)。为了解决这个问题,假设响应具有
类别(foo、bar、baz),我将按以下方式编写reducer:

export default function tweetReducer(state = initialState, action) {
  switch (action.type) {
    case FETCH_TWEETS_SUCCESS:
      return {
          ...state,
          [action.data.category]: action.data
      }
    default:
      return state;
  }
}
然后,您可以在
tweet列中执行以下操作:

class TweetColumn extends Component {

  componentDidMount() {
    this.props.fetchTweets(this.props.column)
  }

  render() {
    const { column } = this.props;
    const tweetItems = this.props.tweets[column].map(tweet => (
      <div key={ tweet.id }>
        { tweet.name }
      </div>
    )
    return (
      <div className="box-content">
        { tweetItems }
      </div>
    )
  }
}

const mapStateToProps = state => ({
  tweets: state.tweets
})

const mapDispatchToProps = dispatch => ({
  fetchTweets: column => dispatch(fetchTweets(column))
})

export default connect(
  mapStateToProps,
  mapDispatchToProps,
)( TweetColumn )
类TweetColumn扩展组件{
componentDidMount(){
this.props.fetchTweets(this.props.column)
}
render(){
const{column}=this.props;
const tweetItems=this.props.tweets[column].map(tweet=>(
{tweet.name}
)
返回(
{tweetItems}
)
}
}
常量mapStateToProps=状态=>({
tweets:state.tweets
})
const mapDispatchToProps=调度=>({
fetchTweets:column=>dispatch(fetchTweets(column))
})
导出默认连接(
MapStateTops,
mapDispatchToProps,
)(推特专栏)


您必须进行一些验证,以确保
tweets[列]
存在,但你明白了。

使用
道具???@xadm只需将键道具传递给子组件?这不起作用。键应该用于所有相同类型的孩子,以帮助区分他们…case..redux…你可能正在寻找你能告诉我们如何在你的redux reducer中更新
tweets
吗?我猜g您在成功的api响应导致的每个操作上都覆盖了它。@nebuler更新了问题使用
道具???@xadm只需将键道具传递给子组件?这不起作用。所有相同类型的子组件都应该使用键来帮助区分它们…case..redux…您可能正在寻找的是什么?您能给我们看看吗如何在redux reducer中更新
tweets
?我猜您在成功的api响应导致的每个操作上都覆盖了它。@nebuler更新了问题响应确实包含类别。但是数据在呈现
tweetItems
后似乎会填充,因此
此.props.tweets[列]
始终是未定义的。如果(tweets.length==0){return null}
导致它永远不会呈现。@dan klasson你能在你的问题中添加
fetchTweets
的实现吗?@dan klasson我指的是
fetchTweets
函数的实现。我猜问题是你没有在
fetchTweets
内部调度类型为
fetchTweets\u SUCCESS
的操作,但我不能100%肯定,除非我看到您是如何实施的。啊,对不起。添加了操作too@dan-klasson看到我更新的答案,我在最后添加了
mapDispatchToProps
。响应中确实包含了类别。但是数据在呈现
tweetItems
后似乎会填充,所以
这个.props.tweets[列]
始终是未定义的。如果(tweets.length==0){return null}
导致它永远不会呈现。@dan klasson你能在你的问题中添加
fetchTweets
的实现吗?@dan klasson我指的是
fetchTweets
函数的实现。我猜问题是你没有在
fetchTweets
内部调度类型为
fetchTweets\u SUCCESS
的操作,但我不能100%肯定,除非我看到您是如何实施的。啊,对不起。添加了操作too@dan-klasson看到我更新的答案,我在最后添加了
mapDispatchToProps