react natvie根据用户的选择显示不同的滚动视图

nuypyhwy  于 2023-03-03  发布在  React
关注(0)|答案(1)|浏览(111)

我克隆了一个前端的todo应用程序,点击“工作”或“旅行”按钮,它会自动显示适合该按钮的列表。

import { StatusBar } from "expo-status-bar";
import React, { useEffect, useState } from "react";
import {
  StyleSheet,
  Text,
  View,
  TouchableOpacity,
  TextInput,
  ScrollView,
} from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { theme } from "./colors";

const STORAGE_KEY = "@toDos";

export default function App() {
  const [working, setWorking] = useState(true);
  const [text, setText] = useState("");
  const [toDos, setToDos] = useState({});
  useEffect(() => {
    loadToDos();
  }, []);
  const travel = () => setWorking(false);
  const work = () => setWorking(true);
  const onChangeText = (payload) => setText(payload);
  const saveToDos = async (toSave) => {
    await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(toSave));
  };
  const loadToDos = async () => {
    const s = await AsyncStorage.getItem(STORAGE_KEY);
    setToDos(JSON.parse(s));
  };

  const addToDo = async () => {
    if (text === "") {
      return;
    }
    const newToDos = {
      ...toDos,
      [Date.now()]: { text, working },
    };
    setToDos(newToDos);
    await saveToDos(newToDos);
    setText("");
  };
  return (
    <View style={styles.container}>
      <StatusBar style="auto" />
      <View style={styles.header}>
        <TouchableOpacity onPress={work}>
          <Text
            style={{ ...styles.btnText, color: working ? "white" : theme.grey }}
          >
            Work
          </Text>
        </TouchableOpacity>
        <TouchableOpacity onPress={travel}>
          <Text
            style={{
              ...styles.btnText,
              color: !working ? "white" : theme.grey,
            }}
          >
            Travel
          </Text>
        </TouchableOpacity>
      </View>
      <TextInput
        onSubmitEditing={addToDo}
        onChangeText={onChangeText}
        returnKeyType="done"
        value={text}
        placeholder={
          working ? "What do you have to do?" : "Where do you want to go?"
        }
        style={styles.input}
      />
      <ScrollView>
        {Object.keys(toDos).map((key) =>
          toDos[key].working === working ? (
            <View style={styles.toDo} key={key}>
              <Text style={styles.toDoText}>{toDos[key].text}</Text>
            </View>
          ) : null
        )}
      </ScrollView>
    </View>
  );
}

在scrollview标记中,我理解如果“toDos[key].working === working”,显示工作的待办事项列表是可以理解的,但如果不是,它不应该什么都不显示吗?我不明白它怎么会显示旅行的待办事项列表,即使我没有采取任何行动
这个代码是我正在听的一个讲座中的现成代码。

yqkkidmi

yqkkidmi1#

看起来代码在默认情况下同时显示了工作和旅行待办事项列表,而不管用户是否单击了“Work”或“Travel”按钮。
这是因为working状态变量被初始化为true,这意味着working默认为true,并且Object.keys(toDos)循环将始终显示toDos状态对象中的所有todo项。
要解决此问题,您可以将工作状态变量初始化为null或undefined,而不是true。然后,您可以更新Object.keys(toDos)循环,以仅显示与当前工作状态变量匹配的待办事项,并添加复选框,以仅在单击按钮时显示待办事项列表:

const [working, setWorking] = useState(); // initialize to null or undefined

// ...

const addToDo = async () => {
  if (text === "") {
    return;
  }
  const newToDos = {
    ...toDos,
    [Date.now()]: { text, working },
  };
  setToDos(newToDos);
  await saveToDos(newToDos);
  setText("");
};

return (
  <View style={styles.container}>
    <StatusBar style="auto" />
    <View style={styles.header}>
      <TouchableOpacity onPress={() => setWorking(true)}> // update working state when button is clicked
        <Text style={{ ...styles.btnText, color: working === true ? "white" : theme.grey }}>Work</Text>
      </TouchableOpacity>
      <TouchableOpacity onPress={() => setWorking(false)}> // update working state when button is clicked
        <Text style={{ ...styles.btnText, color: working === false ? "white" : theme.grey }}>Travel</Text>
      </TouchableOpacity>
    </View>
    {working !== undefined && ( // display todo list only when a button is clicked
      <>
        <TextInput
          onSubmitEditing={addToDo}
          onChangeText={onChangeText}
          returnKeyType="done"
          value={text}
          placeholder={
            working === true ? "What do you have to do?" : "Where do you want to go?"
          }
          style={styles.input}
        />
        <ScrollView>
          {Object.keys(toDos).map((key) =>
            toDos[key].working === working ? (
              <View style={styles.toDo} key={key}>
                <Text style={styles.toDoText}>{toDos[key].text}</Text>
              </View>
            ) : null
          )}
        </ScrollView>
      </>
    )}
  </View>
);

相关问题