【问题标题】:Using componentWillUpdate with switch statements将 componentWillUpdate 与 switch 语句一起使用
【发布时间】:2018-09-18 20:12:46
【问题描述】:

我正在使用 React-NativeReact-Native-Firebase 并试图让我的 Events 组件根据 activityType 属性的值进行不同的 Firebase 查询(然后更新 redux 存储)。

这是工作正常的父组件。当我更改下拉值并将值传递给<Events /> 时,它会更新 state.eventType。

let eventTypes = [{value: 'My Activity'}, {value: 'Friend Activity'}, {value: 'All Activity'}];

  state = {
    showEventFormModal: false,
    eventType: 'Friend Activity'
  }
          <View style={styles.container}>
          <Dropdown
            data={eventTypes}
            value={this.state.eventType}
            containerStyle={{minWidth: 200, marginBottom: 20}}
            onChangeText={val => this.setState({eventType: val})}
          />
          <Events activityType={this.state.eventType}/>
        </View>

这里是事件组件。使用Switch 语句来确定将哪个activityType 传递到props。我遇到的问题是一个无限循环,因为在每个 case 语句中,我正在调度操作以更新导致重新渲染和 componentWillUpdate() 重新触发的存储。我想了解的是处理这个问题的最佳方法是什么?因为很明显我的方法现在不能正常工作。是否有一个共同的反应模式来实现这一目标?

// GOAL: when this components props are updated
// update redux store via this.props.dispatch(updateEvents(events))
// depending on which type of activity was selected

componentWillUpdate() { 
    let events = [];

    switch(this.props.activityType) {
        case 'Friend Activity': // get events collections where the participants contains a friend

            // first get current users' friend list
            firebase.firestore().doc(`users/${this.props.currentUser.uid}`)
            .get()
            .then(doc => {
                return doc.data().friends
            })
            // then search the participants sub collection of the event
            .then(friends => {
                firebase.firestore().collection('events')
                .get()
                .then(eventsSnapshot => {
                    eventsSnapshot.forEach(doc => {
                        const { type, date, event_author, comment } = doc.data();
                        let event = {
                            doc, 
                            id: doc.id,
                            type,
                            event_author,
                            participants: [],
                            date,
                            comment,
                        }
                        firebase.firestore().collection('events').doc(doc.id).collection('participants')
                        .get()
                        .then(participantsSnapshot => {
                            for(let i=0; i<participantsSnapshot.size;i++) {
                                if(participantsSnapshot.docs[i].exists) {
                                    // if participant uid is in friends array, add event to events array
                                    if(friends.includes(participantsSnapshot.docs[i].data().uid)) {
                                        // add participant to event
                                        let { displayName, uid } = participantsSnapshot.docs[i].data();
                                        let participant = { displayName, uid }
                                        event['participants'].push(participant)
                                        events.push(event)
                                        break;
                                    }
                                }
                            }
                        })
                        .then(() => {
                            console.log(events)
                            this.props.dispatch(updateEvents(events))
                        })
                        .catch(e => {console.error(e)})
                    })
                })
                .catch(e => {console.error(e)})
            })
        case 'My Activity': // get events collections where event_author is the user
            let counter = 0;
            firebase.firestore().collection('events').where("event_author", "==", this.props.currentUser.displayName) 
            .get()
            .then(eventsSnapshot => {
                eventsSnapshot.forEach(doc => {
                    const { type, date, event_author, comment } = doc.data();
                    let event = {
                        doc, 
                        id: doc.id,
                        type,
                        event_author,
                        participants: [],
                        date,
                        comment,
                    } 
                    // add participants sub collection to event object
                    firebase.firestore().collection('events').doc(event.id).collection('participants')
                    .get()
                    .then(participantsSnapshot => {
                        participantsSnapshot.forEach(doc => {
                            if(doc.exists) {
                                // add participant to event
                                let { displayName, uid } = doc.data();
                                let participant = { displayName, uid }
                                event['participants'].push(participant)
                            }
                        })
                        events.push(event);
                        counter++;
                        return counter;
                    })
                    .then((counter) => {
                        // if all events have been retrieved, call updateEvents(events)
                        if(counter === eventsSnapshot.size) {
                            this.props.dispatch(updateEvents(events))
                        }
                    })
                })
            })
        case 'All Activity':
            // TODO
            // get events collections where event_author is the user 
            // OR a friend is a participant
    }
}

【问题讨论】:

    标签: reactjs firebase react-native google-cloud-firestore react-native-firebase


    【解决方案1】:

    更新商店最好对用户操作进行。所以,我会在 Dropdown onChange 事件中更新商店,而不是在 componentWillUpdate 函数中。

    【讨论】:

      【解决方案2】:

      在发现我可以通过componentDidUpdate 访问prevProps 后,我想出了一种干净的方法来处理这个问题。这样我可以将之前的 activityType 与当前的进行比较,如果它们发生了变化,那么在 componentDidUpdate 上它应该调用 fetchData(activityType)

      class Events extends React.Component {
      
       componentDidMount() {
           // for initial load 
           this.fetchData('My Activity')
       }
      
       componentDidUpdate(prevProps) {     
           if(this.props.activityType !== prevProps.activityType) {
               console.log(`prev and current activityType are NOT equal. Fetching data for ${this.props.activityType}`)
               this.fetchData(this.props.activityType)
           }
       } 
       fetchData = (activityType) => {
          //switch statements deciding which query to perform
            ...
            //this.props.dispatch(updateEvents(events))
       }
      
      }
      

      https://reactjs.org/docs/react-component.html#componentdidupdate

      【讨论】:

        猜你喜欢
        • 2016-01-02
        • 2020-01-12
        • 2021-11-04
        • 1970-01-01
        • 2020-01-10
        • 2023-04-10
        • 1970-01-01
        • 2019-06-17
        • 1970-01-01
        相关资源
        最近更新 更多