代码之家  ›  专栏  ›  技术社区  ›  Danial

反应组件道具接收延迟。(流星JS)

  •  0
  • Danial  · 技术社区  · 6 年前

    我在做一个react native和meteor js项目。 我的问题是,从withTracker()函数接收的道具仅在 组件didupdate(prevProps) 另一个问题是当我把道具直接从父母传给孩子时。因为我的组件没有更新,所以它很晚才收到它们 iconGroups组 露天矿 我用的道具 显示组图标() 直接从父级传递到此组件。 我想打开手风琴部分,通过家长传递给它。但问题是 组件didupdate(prevProps) 由于组件重新呈现,我正在更改状态。

    下面是我的代码

    import React, { Component } from 'react';
    import Meteor, { withTracker } from 'react-native-meteor';
    import {
        View, Image, ScrollView, TouchableOpacity,
    } from 'react-native';
    import PopupDialog from 'react-native-popup-dialog';
    import {Text, Icon, Input, Item, List,} from 'native-base';
    import Accordion from 'react-native-collapsible/Accordion';
    import { Col, Row, Grid } from 'react-native-easy-grid';
    import styles from './styles';
    import CONFIG from '../../config/constant';
    
    import {MO} from "../../index";
    
    const staticUrl = '../../assets/img/icons/';
    
    class IconPickerComponent extends Component {
        constructor(props) {
            super(props);
            this.state = {
                dataSource: [],
                itemName: 'apple1',
                activeSections: 0,
                showAccordian: true,
                accordianData: []
            };
        }
    
        componentDidUpdate(prevProps) {
            if(prevProps.iconGroups !== this.props.iconGroups) {
                let images = this.props.iconGroups.map(icon => icon.images);
                let flatten = [].concat.apply([], images).map(img => { return {name: img, icon: CONFIG.ICON_URL+img+'.png'} })
                this.setState({ filteredItems: flatten, dataSource: flatten, accordianData: this.props.iconGroups });
            }
        }
    
        componentDidMount() {
            this.props.onRef(this);
        }
    
        componentWillUnmount() {
            this.props.onRef(null);
        }
    
        method() {
            // this.setState(...this.state,{
            //     searchText: ''
            // })
            this.iconPicker.show(); // show icon picker
        }
    
        onSearchChange(text) {
            this.setState({
                showAccordian: !(text.length > 0)
            });
            const searchText = text.toLowerCase();
            const filteredItems = this.state.dataSource.filter((item) => {
                const itemText = item.name.toLowerCase();
                return itemText.indexOf(searchText) !== -1;
            });
            this.setState({ filteredItems });
    
        }
    
        onIconSelect(item) {
            this.setState({
                itemName: item,
            });
            this.iconPicker.dismiss();
            if (this.props.onIconChanged) {
                this.props.onIconChanged(item);
            }
        }
        _renderSectionTitle = section => {
            return (
                <View style={styles.content}>
                    <Text></Text>
                </View>
            );
        };
    
        _renderHeader = section => {
            return (
                <View style={styles.accordHeader}>
                    <Text style={{color: 'white'}}>{this.state.showAccordian} - {section.group}</Text>
                    <Text>
                        <Icon style={styles.downArrow} name="ios-arrow-down" />
                    </Text>
                </View>
            );
        };
    
        _renderContent = section => {
            return (
                <View style={styles.accordContent}>
                    {
                        section.images.map((img, key) => (
                            <TouchableOpacity onPress={() => this.onIconSelect(img)} key={key}>
                                <View style={styles.iconsGrid}>
                                    <Image style={styles.image} source={{uri: CONFIG.ICON_URL+ img + '.png'}}/>
                                </View>
                            </TouchableOpacity>
                        ))
                    }
                </View>
            );
        };
    
        _updateSections = activeSections => {
            this.setState({ activeSections });
        };
    
        hasGroupIcons() {
            return this.props.iconGroups.length > 0;
        };
    
        showGroupIcons() {
            if(this.state.showAccordian){
                let openSection;
                if(!!this.props.openSection) {
                    let groupIndex = this.state.accordianData.findIndex(icon => icon.group === this.props.openSection);
                    if(groupIndex !== -1) {
                        openSection = groupIndex;
                    } else {
                        openSection = 0;
                    }
                } else {
                    openSection = 0;
                }
                return(<Accordion
                    sections={this.state.accordianData}
                    activeSections={this.state.activeSections}
                    renderSectionTitle={this._renderSectionTitle}
                    renderHeader={this._renderHeader}
                    renderContent={this._renderContent}
                    onChange={this._updateSections}
                    initiallyActiveSection={openSection} />);
            } else {
                return(<View style={{flexWrap: 'wrap', flexDirection: 'row'}}>
                    {
                        this.state.filteredItems.map((item, key) => (
                            <TouchableOpacity onPress={() => this.onIconSelect(item.name)} key={key}>
                                <View style={styles.iconsGrid}>
                                    <Image style={styles.image} source={{uri: item.icon}}/>
                                </View>
                            </TouchableOpacity>
                        ))
                    }
                </View>)
            }
        };
    
        render() {
            return (
                <PopupDialog
                    overlayOpacity={0.8}
                    overlayBackgroundColor="#414141"
                    dialogStyle={styles.dialogBox}
                    containerStyle={styles.dialogContainer}
                    ref={(popupDialog) => { this.iconPicker = popupDialog; }}
                >
                    <ScrollView>
                        <View style={styles.dialogInner}>
                            <Item searchBar rounded style={styles.searchbar}>
                                <Icon style={styles.searchIcon} name="search" />
                                <Input onChangeText={this.onSearchChange.bind(this)} style={styles.inputSearch} placeholder="Search" />
                            </Item>
                            {
                                this.hasGroupIcons() && this.showGroupIcons()
                            }
                        </View>
                    </ScrollView>
                </PopupDialog>
            );
        }
    }
    
    export default withTracker(params => {
        MO.subscribe('ipSubsId3', 'IconGroups');
        return {
            iconGroups: MO.collection('IconGroups', 'ipSubsId3').find({}),
        };
    })(IconPickerComponent);
    

    我是新来的反应。我假设当道具改变组件重新渲染。

    2 回复  |  直到 6 年前
        1
  •  1
  •   Rajendran Nadar    6 年前

    使用此生命周期方法

    static getDerivedStateFromProps(prevProps, prevState) {
            if(prevProps.iconGroups !== this.props.iconGroups) {
                let images = this.props.iconGroups.map(icon => icon.images);
                let flatten = [].concat.apply([], images).map(img => { return {name: img, icon: CONFIG.ICON_URL+img+'.png'} })
                this.setState({ filteredItems: flatten, dataSource: flatten, accordianData: this.props.iconGroups });
            }
        }
    

    getDerivedStateFromProps 在调用呈现方法之前调用,无论是在初始装载还是在后续更新时。它应该返回一个对象来更新状态,或者返回null来不更新任何内容。

    Read more about this lifecycle method here

        2
  •  0
  •   Danial    6 年前

    我已经解决了这个问题。实际上我的想法是不对的。我以为道具是在构造器和组件willmount中最先收到的。但是我在render()中得到了所有的道具,一切都很好我现在不需要使用任何生命周期方法来使用道具