使用useState钩子基于Web Api将状态动态添加到React Native [英] Add state to React Native dynamically based on Web Api using useState hook

查看:53
本文介绍了使用useState钩子基于Web Api将状态动态添加到React Native的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下问题:

我打算通过Web API获取数据,并在此基础上,React Native将使用FlatList呈现数据.在这种情况下,它将使用子组件(复选框).因此,会有多个复选框.

I intend to fetch data via web API and on its basis, React Native will render it using FlatList. It will use a child component, in this case (Checkbox). So, there will be multiple checboxes.

当我不知道它们的计数时如何创建和更新这些checbox的状态,然后将其状态传递给子组件?

How can I create and update state of these checboxes when I don't know their count and then pass their state to child component?

const data = [{
   id:0,
   product:"A"
   price:30
},
{
   id:1,
   product:"B"
   price:20
},
{
   id:1,
   product:"C"
   price:10
}]

(我挠头)

推荐答案

输出:

这里是一个应用程序的工作示例,该应用程序显示了数据选择并将其流向下一个屏幕,实现了数据提取,并相应地在服务器端执行了

Here is the working example of an app showing data selection and flow of it to the next screen, implement data fetching, and server-side execution accordingly.

import React, { useState, useEffect } from 'react';
import {
  Text,
  View,
  StyleSheet,
  FlatList,
  CheckBox,
  Button,
  Modal,
} from 'react-native';
import Constants from 'expo-constants';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

// You can import from local files
import AssetExample from './components/AssetExample';

// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';

const data = [
  {
    id: 0,
    product: 'A',
    price: 30,
    selected: false,
  },
  {
    id: 2,
    product: 'B',
    price: 20,
    selected: false,
  },
  {
    id: 3,
    product: 'C',
    price: 10,
    selected: false,
  },
];

const Stack = createStackNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Payment" component={PaymentScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

function PaymentScreen({ navigation, route }) {
  const { selected } = route.params;
  return (
    <FlatList
      data={selected}
      renderItem={({ item }) => (
        <Card style={{ margin: 5 }}>
          <View style={styles.card}>
            <View
              style={{
                flexDirection: 'row',
                width: 50,
                justifyContent: 'space-between',
              }}>
              <Text>{item.product}</Text>
            </View>
            <Text>{item.price} USD</Text>
          </View>
        </Card>
      )}
    />
  );
}

function HomeScreen({ navigation }) {
  const [products, setProducts] = useState(data);
  const [showModal, setShowModal] = useState(false);
  const [selected, setSelected] = useState([]);

  const handleChange = (id) => {
    let temp = products.map((product) => {
      if (id === product.id) {
        return { ...product, selected: !product.selected };
      }
      return product;
    });
    setProducts(temp);
  };

  const getSelected = () => {
    let temp = products.filter((product) => product.selected);
    setSelected(products.filter((product) => product.selected));
    console.log(temp);
  };

  useEffect(() => {
    getSelected();
  }, [showModal]);

  return (
    <View style={styles.container}>
      <Modal animationType="slide" transparent={true} visible={showModal}>
        <View style={styles.modalView}>
          <FlatList
            data={selected}
            renderItem={({ item }) => (
              <Card style={{ margin: 5 }}>
                <View style={styles.card}>
                  <View
                    style={{
                      flexDirection: 'row',
                      width: 50,
                      justifyContent: 'space-between',
                    }}>
                    <Text>{item.product}</Text>
                  </View>
                  <Text>{item.price} USD</Text>
                </View>
              </Card>
            )}
          />
          <Text>
            Total :{' '}
            {selected.reduce((acc, curr) => acc + curr.price, 0).toString()}
          </Text>
          <Button
            title={'BUY'}
            onPress={
              selected
                ? () => {
                    setShowModal(false);
                    navigation.navigate('Payment', { selected: selected });
                  }
                : setShowModal(false)
            }
          />
        </View>
      </Modal>
      <FlatList
        data={products}
        renderItem={({ item }) => (
          <Card style={{ margin: 5 }}>
            <View style={styles.card}>
              <View
                style={{
                  flexDirection: 'row',
                  width: 50,
                  justifyContent: 'space-between',
                }}>
                <CheckBox
                  value={item.selected}
                  onChange={() => {
                    handleChange(item.id);
                  }}
                />
                <Text>{item.product}</Text>
              </View>
              <Text>{item.price} USD</Text>
            </View>
          </Card>
        )}
      />
      <Button
        title={'ADD TO CART'}
        onPress={() => {
          setShowModal(true);
          console.log(showModal);
        }}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },

  card: {
    padding: 10,
    margin: 5,
    flexDirection: 'row',
    justifyContent: 'space-between',
  },
  modalView: {
    margin: 20,
    backgroundColor: 'white',
    borderRadius: 20,
    padding: 5,
    justifyContent: 'space-between',
    alignItems: 'center',
    elevation: 5,
  },
});

您可以在此处使用工作代码: Expo快餐

You can play with the working code here: Expo Snack

这篇关于使用useState钩子基于Web Api将状态动态添加到React Native的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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