首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >反应组件道具收到晚。(流星JS)

反应组件道具收到晚。(流星JS)
EN

Stack Overflow用户
提问于 2018-11-22 11:32:04
回答 2查看 958关注 0票数 0

我的工作是一个反应-本土和流星js项目。我的问题是,从withTracker()函数接收的道具只在withTracker()中接收,我在构造函数或componentWillMount中没有得到它们。另一个问题是当我把道具直接从父母传给孩子的时候。由于我的组件不更新showGroupIcons(),所以它会很晚才收到它们,因此iconGroups螺旋桨来自withTracker()方法,而我在此iconGroups中使用的openSection道具直接从父组件传递到该组件。我想打开通过父级传递给它的Accordian节。但问题在于,在componentDidUpdate(prevProps)中,由于组件重新呈现的原因,我正在更改状态。默认情况下,openSection变量为零。当道具出现时,它的值会发生变化,这是我所需要的,但是Accordian不更新。

下面的是我的代码

代码语言:javascript
复制
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);

我是新来的反应。我假设当道具更改组件重新呈现时。

EN

回答 2

Stack Overflow用户

发布于 2018-11-22 13:57:27

使用此生命周期方法

代码语言:javascript
复制
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 });
        }
    }

在调用render方法之前,在初始挂载和后续更新中都会调用getDerivedStateFromProps。它应该返回一个对象来更新状态,或者返回null来更新任何内容。

此处了解更多有关此生命周期方法的信息。

票数 1
EN

Stack Overflow用户

发布于 2018-11-24 10:17:25

我已经解决了这个问题。其实我的观念不对。我认为道具首先是在构造函数和componentWillMount中接收的。但是我在render()中得到了所有的道具,一切都很好,现在不用使用任何生命周期方法来使用道具了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53430032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档