在将prop转移到那里之后如何重新渲染React Native组件

时间:2019-01-07 14:38:41

标签: javascript reactjs react-native

我正在尝试通过用户名搜索来实现用户列表。

在父级组件SearchListOfUsers中更改道具usernameFilter并将其传递给子级SearchPeopleScreen之后,我遇到了重新渲染SearchListOfUsers的问题。

我知道组件state更改后应该重新呈现自己,但是在我的情况下,子组件的状态也不会改变。如何更新我的孩子补偿。 SearchListOfUsers经过道具usernameFilter后通过了?

这是我父母的礼物。 SearchPeopleScreen

export default class SearchPeopleScreen extends Component {

constructor(props) {
    super(props);
    this.state = {
        ...
        usernameFilter: ''
    }
}

render() {
    return(
        <Container>

            <Header style = {searchPeopleScreenStyle.header} searchBar>
                <Title style = {searchPeopleScreenStyle.title}>
                    Search
                </Title>

                <Right/> 
                <Item style = {searchPeopleScreenStyle.searchFieldWrapper}>
                     <IconSimpleLine name = 'magnifier' color = {placeholder} size = {20} style = {{padding: 10}}/>
                     <TextInput 
                               underlineColorAndroid = 'transparent'
                               onChangeText = {(text) => {
                                  this.setState({usernameFilter: text});
                               }}
                               placeholder = 'Type username'
                               style = {searchPeopleScreenStyle.searchInput}
                                    maxLength = {15}
                       />
                 </Item>

            </Header>

            <Content>
                <ScrollView contentContainerStyle = {searchPeopleScreenStyle.container}>

                    ...

                    {/* Search screen's body */}
                    <SearchListOfUsers searchOption = {this.state.searchOption}
                                        usernameFilter = {this.state.usernameFilter}/>

                </ScrollView>
            </Content>

        </Container>
    )
}
}

这是我的孩子。 SearchListOfUsers

export default class SearchListOfUsers extends Component {

constructor(props) {
    super(props);

    this.state = {
        usersDataArray: [],
        usernameFilter: this.props.usernameFilter
    };

    this.arrayHolder = [];
    console.warn('1 - ' + this.state.usernameFilter)
}

componentDidMount() {
    this.getAllUsersData()

    console.warn(this.state.usernameFilter)

    if(this.state.usernameFilter) {
        this.filterUsers();
    }
}

getAllUsersData = () => {
    return new Promise((resolve, reject) => {
        // getting users data and creating an array 
        ...
        allUsersDataArray.push({...});

        this.setState({
            usersDataArray: allUsersDataArray
        });

        resolve();
    })
}

filterUsers = () => {
    const newUsersDataArray = this.arrayHolder.filter((user) => {
        const usernameInTheList = user.userUsername.toUpperCase();
        const inputtedUsername = this.state.usernameFilter.toUpperCase();
        return usernameInTheList.includes(inputtedUsername);
    });

    this.setState({
        usersDataArray: newUsersDataArray
    })
}

render() {
    return(
          <Content contentContainerStyle = {searchPeopleScreenStyle.listOfUsersWrapperGlobal}>
                <FlatList
                    data = {this.state.usersDataArray}
                    keyExtractor = {(item) => (item.userId)}
                    renderItem = {({item}) => (
                        <UserListItem
                                        country = {item.userCountry}
                                        username = {item.userUsername}
                                        ...
                        />
                    )}
                />
            </Content>
        )
    }
}
}

2 个答案:

答案 0 :(得分:2)

如果您需要基于上级组件的选择来过滤数据,那么您也应该在那里过滤集合。过滤完集合后,应将其传递给子组件。

在这种情况下,子组件应该纯粹是表示性的和静态的。它不关心过滤数据或更新其组件状态等,它只想呈现传递的任何道具。 searchOption,usernameFilter,dataCollection

答案 1 :(得分:0)

您可以使用componentDidMount lifecyle方法过滤用户,这意味着该方法仅在子组件的安装过程中运行一次。

您可以在渲染方法中进行过滤

filterUsers = () => {
    if(!this.props.usernameFilter.length) return this.state.usersDataArray

    return this.state.usersDataArray.map((user) => {
        const usernameInTheList = user.userUsername.toUpperCase();
        const inputtedUsername = this.props.usernameFilter.toUpperCase();
        return usernameInTheList.includes(inputtedUsername);
    });
}

render() {
    return(
          <Content contentContainerStyle = {searchPeopleScreenStyle.listOfUsersWrapperGlobal}>
                <FlatList
                    data = {this.filterUsers()}
                    keyExtractor = {(item) => (item.userId)}
                    renderItem = {({item}) => (
                        <UserListItem
                                        country = {item.userCountry}
                                        username = {item.userUsername}
                                        ...
                        />
                    )}
                />
            </Content>
        )
    }
}