代码之家  ›  专栏  ›  技术社区  ›  dan-klasson

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

  •  0
  • dan-klasson  · 技术社区  · 7 年前

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

    <ChildComponent category="foo" />
    <ChildComponent category="bar" />
    <ChildComponent category="baz" />
    

    子组件根据道具类别值调用api:

    http://example.com/listings.json?category=foo
    

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

    A. solution to this problem seems to be given here

    我的 子组件 看起来像这样:

    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 default function tweetReducer(state = initialState, action) {
      switch (action.type) {
        case FETCH_TWEETS_SUCCESS:
          return {
        ...state,
        [action.data[0].user.screen_name]: action.data
          }
        default:
          return state;
      }
    }
    
    export default combineReducers({
        tweets: tweetReducer,
    })
    

    行动:

    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}))
    
    }
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   nebuler    7 年前

    您每次都在进行api调用 TweetColumn 安装了。如果你有多个 state.tweets.items . 这是因为您正在发送相同的操作 FETCH_TWEETS_SUCCESS category (foo,bar,baz),我将用以下方式编写减速机:

    export default function tweetReducer(state = initialState, action) {
      switch (action.type) {
        case FETCH_TWEETS_SUCCESS:
          return {
              ...state,
              [action.data.category]: action.data
          }
        default:
          return state;
      }
    }
    

    推文栏 组成部分:

    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 )
    

    您必须进行一些验证以确保 tweets[column]