直到第二次按下按钮状态才会改变?添加回调会抛出错误“不变量违反:传递的参数无效"; [英] State does not change until the second button press? Adding a call back throws an error "invariant violation: invalid argument passed"

查看:47
本文介绍了直到第二次按下按钮状态才会改变?添加回调会抛出错误“不变量违反:传递的参数无效";的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试呈现一个包含商店名称的 Flatlist.单击商店名称后,应显示有关商店的更多信息.

I'm trying to render a Flatlist that contains a store name. Upon clicking the store name, more information about the store should be displayed.

我试图改变状态,然后使用

I attempted to change state and then use

{this.renderMoreDetails(item) && this.state.moreDetailsShown}

获取显示的附加信息.但是,通过 console.log 可以清楚地看到,状态仅在第二次按下按钮后才会更改.

to get the additional information to appear. However, it was clear via console.log that state was only changed after a second button press.

从我在这篇文章中读到的内容1 和这篇文章 2 好像我需要一个回调函数作为我的 setState() 的附加参数.
我尝试添加一个回调函数(可能不正确,但此时我非常迷茫)并且只得到了更多错误.

From what I read in this article 1 and this article 2 it seemed as though I needed a callback function as an additional parameter to my setState().
I tried adding a callback function(probably incorrect, but I'm extremely lost at this point) and only got more errors.

我知道我可以访问来自 FlatList 中的 renderItem 的所有数据.如何让它在点击时显示?

I know that I have access to all of the data from renderItem inside FlatList. How do I make it appear upon click?

    import React, { Component } from 'react';
import { 
        View,
        FlatList,
        Text,
        TouchableWithoutFeedback,
        ListView,
        ScrollView
        } from 'react-native'

import { NavigationActions } from 'react-navigation';
import { Header, Card, CardSection } from '../common';
import Config from '../Config';

export default class Costco extends Component<Props> {
    constructor(props) {
        super(props);
        this.state = {
            stores: [],
            selectedItem: {id: null},
        };
    }

    componentWillMount() {
        const obj = Config.costcoThree;
        const costcoArr = Object.values(obj);

        this.setState({
            stores: costcoArr,
        })

    }

    renderListOfStores() {
        return <FlatList 
          data={this.state.stores} 
          renderItem={ ({item}) => this.singleStore(item)} 
          keyExtractor={(item) => item.id} 
          extraData={this.state.selectedItem} />
    }

    singleStore(item) {
        console.log(this.state.selectedItem.id)
        return item.id === this.state.selectedItem.id ?
            <TouchableWithoutFeedback

                onPress={() => this.selectStore(item)}
            >
                <View>
                    <Text>{item.branchName}</Text>
                    <Text>Opening Time {item.openingTime}</Text>
                    <Text>Closing Time {item.closingTime}</Text>
                    <Text>Address {item.dongAddKor}</Text>
                </View>
            </TouchableWithoutFeedback>
        : 
        <TouchableWithoutFeedback>
            <View>
                <Text>{item.branchName}</Text>
                <Text>Only showing second part</Text>
            </View>
        </TouchableWithoutFeedback>

    }

    selectStore(item) {

        this.setState({selectedItem: item});
        console.log('repssed');
    }

    render() {
        return(
            <ScrollView> 
                <Header headerText="Costco"/>
                <Text>hello</Text>
                {this.renderListOfStores()}
            </ScrollView>
        )
    }
}

推荐答案

作为一种变通方法,您可以拥有一个状态来保持您选择的项目展开(或其他类似视图),然后您可以使用一些条件进行渲染您的平面列表数据.

as a workaround you can have a state that maintain your selected item to expand(or something like another view) and then you can use some conditions to work for render your flat list data.

考虑下面的代码,如果您需要更多说明,请告诉我.

Consider the below code and let me know if you need some more clarification.

import React, { Component } from 'react';
import {
  Platform,
  StyleSheet,
  Text,FlatList,TouchableNativeFeedback,
  View
} from 'react-native';

export default class App extends Component<Props> {

    constructor(props) {
      super(props);

      this.state = {
        response: [],
        selectedItem: {id: null},
      };
    }


    userListLayout() {
        const {response} = this.state;
        return <FlatList data={response} renderItem={ ({item}) => this.singleUserLayout(item)} keyExtractor={(item) => item.email} extraData={this.state.selectedItem} />
    }


    singleUserLayout(item) {
        return item.id == this.state.selectedItem.id ? 
            <TouchableNativeFeedback onPress={() => this.userSelected(item)}>
            <View style={{flex:1, borderColor: 'black', borderWidth: 1}}>
            <Text style={{padding: 10, fontSize: 25}}>{item.email}</Text>
            <Text style={{padding: 10,fontSize: 20}}>{item.name}</Text>
            </View>
            </TouchableNativeFeedback>

        : <TouchableNativeFeedback onPress={() => this.userSelected(item)}><Text style={{padding: 10,fontSize: 20}}>{item.email}</Text></TouchableNativeFeedback>
    }

    userSelected(item) {
        console.log(item)
        this.setState({selectedItem: item})
    }

    componentDidMount() {
      fetch("https://jsonplaceholder.typicode.com/users")
        .then(data => data.json())
        .then(response => this.setState({response}))
    }

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>HI THERE</Text>
        {this.userListLayout()}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

这篇关于直到第二次按下按钮状态才会改变?添加回调会抛出错误“不变量违反:传递的参数无效";的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆