0

在我的应用程序中,我从 useEffect 挂钩内的服务器获取用户数据并设置initialState. useReducer当文本输入更改时发生动作调度时,initialState 会重置而不是更新,因此我无法在输入中键入单词。请问有人能解决这个问题吗?我对减速器反应还很陌生。我已附上相关代码。谢谢。

EditProfile.js

const EditProfile = ({ navigation, route }) => {
  const userid = route.params.userid;
  const { user } = React.useContext(AuthContext);
  const [userData, setUserData] = React.useState(null);

  const initialState = {
    name: userData ? (userData.name ? userData.name : "") : "",
    dob: userData ? (userData.dob ? userData.dob.toDate() : "") : "",
    phone: userData ? (userData.phone ? userData.phone : "") : "",
    location: userData ? (userData.location ? userData.location : "") : "",
    caption: userData ? (userData.caption ? userData.caption : "") : "",
  };

  React.useEffect(() => {
    async function fetchData() {
      const response = await getUserData(userid);
      setUserData(response);
    }
    fetchData();
  }, []);

  const reducer = (state, action) => {
    switch (action.type) {
      case "nameInputChange":
        return {
          ...state,
          name: action.name,
        };
      case "dobInputChange":
        return {
          ...state,
          dob: action.dob,
        };
      case "phoneInputChange":
        return {
          ...state,
          phone: action.phone,
        };
      case "locationInputChange":
        return {
          ...state,
          location: action.location,
        };
      case "captionInputChange":
        return {
          ...state,
          caption: action.caption,
        };
    }
  };

  const [data, dispatch] = React.useReducer(reducer, initialState);

  const nameInputChange = (value) => {
    dispatch({
      type: "nameInputChange",
      name: value,
    });
    console.log("Name: ", initialState.name);
  };

  const dobInputChange = (date) => {
    dispatch({
      type: "dobInputChange",
      dob: date,
    });
  };

  const phoneInputChange = (value) => {
    dispatch({
      type: "phoneInputChange",
      phone: value,
    });
  };

  const locationInputChange = (value) => {
    dispatch({
      type: "locationInputChange",
      location: value,
    });
  };

  const captionInputChange = (value) => {
    dispatch({
      type: "captionInputChange",
      caption: value,
    });
  };

  return (
    <View>
      <FlatList
        showsVerticalScrollIndicator={false}
        ListHeaderComponent={() => (
          <View>
            <TouchableOpacity>
              <Image
                source={require("../assets/images/profile.jpg")}
                style={{ width: "98%", height: "98%", borderRadius: 59 }}
              />
              <View>
                <Entypo name="camera" color="#8000e3" size={18} />
              </View>
            </TouchableOpacity>
            <View>
              <VerticalNameInput
                type="name"
                label="Full Name"
                placeholder="Full name"
                color="#9798ac"
                placeholder="enter your full name"
                onChangeText={(value) => nameInputChange(value)}
                value={initialState.name}
              />
              <VerticalDateInput
                label="Date of Birth"
                color="#9798ac"
                dobInputChange={dobInputChange}
                initialState={initialState}
              />
            </View>
            <View>
              <VerticalNameInput
                type="mobile"
                label="Mobile"
                color="#9798ac"
                placeholder="mobile number"
                onChangeText={(value) => phoneInputChange(value)}
                value={initialState.phone}
              />
              <VerticalNameInput
                type="location"
                label="Location"
                color="#9798ac"
                placeholder="city and country"
                onChangeText={(value) => locationInputChange(value)}
                value={initialState.location}
              />
            </View>
            <View>
              <VerticalNameInput
                type="caption"
                label="Profile Caption"
                color="#9798ac"
                placeholder="enter about yourself"
                onChangeText={(value) => captionInputChange(value)}
                value={initialState.caption}
              />
            </View>
          </View>
        )}
      />
      <View style={{ position: "relative", top: -90, left: 200 }}>
        <FloatingAction
          onPressMain={() => {
            updateUser(userid, userData);
          }}
          floatingIcon={<Entypo name="check" size={28} color="#fff" />}
        />
      </View>
    </View>
  );
};

export default EditProfile;

垂直名称输入.js

const VerticalNameInput = ({ label, color, placeholder, type, ...rest }) => {
  return (
    <View>
      <Text>
        {label}
      </Text>
      <View>
        <View>
          {type === "name" ? (
            <AntDesign name="user" color="#000" size={15} />
          ) : type === "mobile" ? (
            <AntDesign name="mobile1" color="#000" size={15} />
          ) : type === "location" ? (
            <EvilIcons name="location" color="#000" size={20} />
          ) : type === "caption" ? (
            <Ionicons
              name="information-circle-outline"
              color="#000"
              size={18}
            />
          ) : null}
        </View>
        <TextInput
          style={{ width: "85%", height: "100%" }}
          numberOfLines={1}
          placeholder={placeholder}
          placeholderTextColor={color}
          {...rest}
        />
      </View>
    </View>
  );
};

export default VerticalNameInput;

垂直日期输入.js

const VerticalDateInput = ({ label, color, dobInputChange, initialState }) => {
  const [date, setDate] = React.useState(new Date());
  const [open, setOpen] = React.useState(false);

  return (
    <View>
      <Text>
        {label}
      </Text>
      <View>
        <View>
          <AntDesign name="calendar" color="#000" size={15} />
        </View>
        <View>
          <Text style={{ marginLeft: 10 }}>
            {initialState.dob
              ? initialState.dob.toDateString()
              : new Date().toDateString()}
          </Text>
          <TouchableOpacity
            style={{ marginRight: 10 }}
            onPress={() => setOpen(true)}
          >
            <AntDesign name="caretdown" color="#000" size={12} />
          </TouchableOpacity>
        </View>
        <DatePicker
          maximumDate={new Date()}
          mode="date"
          modal
          open={open}
          date={initialState.dob ? initialState.dob : date}
          onConfirm={(date) => {
            setOpen(false);
            setDate(date);
            dobInputChange(date);
          }}
          onCancel={() => {
            setOpen(false);
          }}
        />
      </View>
    </View>
  );
};

export default VerticalDateInput;
4

1 回答 1

0

尝试在减速器中添加“默认”案例返回当前状态。您可能会分派一些未知的操作,并且 reducer 作为结果返回 undefined。

const reducer = (state = initialState, action) => {
  switch (action.type) {
    default:
      // If this reducer doesn't recognize the action type, or doesn't
      // care about this specific action, return the existing state unchanged
      return state

} }

于 2021-12-29T07:32:56.600 回答