React Native中如何通过PATCH请求正确更新用户数据?
React Native 用户数据更新动态传参失效问题
我开发了一个React Native应用,尝试更新用户数据(如firstname、lastname等)。调用API接口时,只有硬编码参数能正常更新,动态传递参数无法生效,旧数据不会被替换。
API请求服务代码
export const AccountUpdateRequest = async ( first_name, last_name, email, username, password, password2 ) => { const token = await retrieveToken(); console.log("response"); try { if (token) { const response = await fetch("http://192.168.1.65:8000/api/user/me/", { method: "PATCH", headers: { Authorization: `Token ${token}`, "Content-Type": "application/json", }, body: JSON.stringify({ first_name: first_name, last_name: last_name, email: email, username: username, password: password, password2: password2, }), }); return await response.json(); } else { throw new Error(token); } } catch (error) { //console.log(error); error("can't retrieve data"); } };
动态传参时,返回旧数据(比如输入firstName为helloTherejjj,返回仍为旧值):
Object { "email": "n@n.nl", "first_name": "helloThere", "last_name": "jooh", "username": "username999", }
硬编码参数则能正常更新:
body: JSON.stringify({ first_name: "helloThere", last_name: "jooh", email: "hello@email.nl", username: "username999", password: "1234567890", password2: "1234567890", }),
Context中的请求方法
const UpdateUserProfileRequest = async ( first_name, last_name, email, username, password, password2 ) => { setIsLoading(true); AccountUpdateRequest(first_name, last_name, email, username, password, password2) .then((u) => { console.log(u); setUser(u); setIsLoading(false); }) .catch((e) => { setIsLoading(false); setError(e.toString()); }); };
页面组件代码
export const SetScreen = ({ navigation }) => { const [username, setUsername] = useState(""); const [firstName, setFirstName] = useState(""); const [lastName, setLastName] = useState(""); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [password2, setPassword2] = useState(""); const { isLoading, onLogout, error, passwordValidError, UpdateUserProfileRequest, } = useContext(AuthContext); const changedText = (evt) => { console.log("changed", firstName); }; useEffect(() => { AccountRequest().then((data) => { setFirstName(data.first_name); setLastName(data.last_name); setEmail(data.email); setUsername(data.username); setPassword(data.password); setPassword2(data.password2); }); }, []); return ( <> <ScrollView style={styles.scrollView}> <AccountBackground> <AccountCover /> <Title>Instellingen</Title> <AccountContainer> <AuthInput label="Voornaam" value={firstName} autoCapitalize="none" onChange={changedText} onChangeText={(fn) => setFirstName(fn)} /> <Spacer size="large"> <AuthInput label="Achternaam" value={lastName} autoCapitalize="none" textContentType="Achternaam" onChangeText={(ln) => setLastName(ln)} /> </Spacer> <Spacer size="large"> <AuthInput label="E-mail" value={email} textContentType="emailAddress" keyboardType="email-address" autoCapitalize="none" onChangeText={(em) => setEmail(em)} /> </Spacer> <Spacer size="large"> <AuthInput label="Username" value={username} textContentType="username" keyboardType="username" autoCapitalize="none" onChangeText={(un) => setUsername(un)} /> </Spacer> <Spacer size="large"> <AuthInput label="Wachtwoord" value={password} textContentType="password" secureTextEntry autoCapitalize="none" onChangeText={(p) => { setPassword(p); }} error={passwordValidError} /> </Spacer> <Spacer size="large"> <AuthInput label="Herhaal wachtwoord" value={password2} textContentType="password2" secureTextEntry autoCapitalize="none" onChangeText={(pas) => setPassword2(pas)} /> </Spacer> {error && ( <ErrorContainer size="large"> <Text variant="error">{error}</Text> </ErrorContainer> )} <Spacer size="large"> {!isLoading ? ( <AuthButton ion-icon name="log-out-outline" mode="contained" onPress={() => onLogout()}> uitloggen </AuthButton> ) : ( <ActivityIndicator animating={false} /> )} </Spacer> <Spacer size="large"> <AuthButton icon="email" mode="contained" onPress={() => UpdateUserProfileRequest()}> save </AuthButton> </Spacer> </AccountContainer> <Spacer size="large"> <AuthButton mode="contained" onPress={() => navigation.goBack()}> Back </AuthButton> </Spacer> </AccountBackground> </ScrollView> </> ); };
AuthInput组件
export const AuthInput = styled(TextInput)` width: 200px; background-color: #c6daf7; `;
尝试过的修改(未解决问题)
修改保存按钮的onPress事件:
<Spacer size="large"> <AuthButton icon="email" mode="contained" onPress={(event) => { event.persist(); UpdateUserProfileRequest( first_name, lastName, email, username, password, password2); }}> save </AuthButton> </Spacer>
解决方案
1. 修复参数名拼写错误
在修改后的onPress代码里,传递的第一个参数是first_name,但组件中定义的状态是firstName(驼峰命名),参数名不匹配导致传递了未定义的值。修改为:
<Spacer size="large"> <AuthButton icon="email" mode="contained" onPress={() => { UpdateUserProfileRequest( firstName, lastName, email, username, password, password2 ); }}> save </AuthButton> </Spacer>
2. 确认参数传递正确性
在AccountUpdateRequest中添加日志,打印传入的参数,验证动态参数是否正确传入:
export const AccountUpdateRequest = async ( first_name, last_name, email, username, password, password2 ) => { const token = await retrieveToken(); // 打印传入的参数,确认是否正确 console.log("传入的更新参数:", {first_name, last_name, email, username, password, password2}); try { if (token) { const response = await fetch("http://192.168.1.65:8000/api/user/me/", { method: "PATCH", headers: { Authorization: `Token ${token}`, "Content-Type": "application/json", }, body: JSON.stringify({ first_name: first_name, last_name: last_name, email: email, username: username, password: password, password2: password2, }), }); const result = await response.json(); console.log("API返回结果:", result); return result; } else { throw new Error("未获取到token"); } } catch (error) { console.error("更新请求出错:", error); throw new Error("无法获取数据"); } };
3. 密码字段特殊处理
通常后端不会返回用户明文密码,初始化时password和password2状态可能为空。如果不需要更新密码,可只传递需要修改的字段,避免空值影响请求:
body: JSON.stringify({ first_name: first_name, last_name: last_name, email: email, username: username, // 仅当密码不为空时传递 ...(password && {password}), ...(password2 && {password2}), }),
内容的提问来源于stack exchange,提问作者mightycode Newton
相关产品推荐
相关产品推荐

