【问题标题】:React Native: onChangeText is not updating hook stateReact Native:onChangeText 没有更新钩子状态
【发布时间】:2021-06-16 02:33:41
【问题描述】:

所以我试图在我的 react 本机应用程序中做一些非常简单的事情,但它似乎无法正常工作。我的本机应用程序中有一个组件,允许用户创建帖子。用户可以简单地输入他们想要作为帖子正文的文本。当然,我决定为此使用TextInput 组件,并且我正在使用onChangeText={text => onChangeText(text)} 设置我的身体状态。当我单击标题右上角的create_post 按钮时,我得到“”作为正文的值。

我的应用程序中还有其他文本输入组件可以按预期工作,但由于某种原因,这个不是。我在网上查了一遍,似乎没有人有这个问题。他们只在类组件中存在问题,而不是像我在这里的功能组件:

import React,{useLayoutEffect,useState} from 'react'
import { TextInput,ScrollView } from 'react-native'
import { Button } from './../components/Button';

const CreatePost = ({navigation,route}) => {
    const [body,onChangeText] = useState('');
    const [media,setMedia] = useState('');

    useLayoutEffect(() => {
        navigation.setOptions({
            title: 'New Post',
            headerRight: () => (
                <Button style={{marginRight:40,fontSize:20}} title="Post" textColor="#0d00ff" onPress={create_post} />
            )
        })
    },[])

    const create_post = () => {
        const timestamp = new Date().toISOString().split('.')[0];

        console.log({body});  // expected: 'some text', result:""
        const post = {
            pid: 0,
            username: 'head_honcho',
            body: body
        }
        
        // makes call to database
        navigation.navigate('HomeTab',{screen: 'Home',params:{post:post}});

    }

    return (
        <ScrollView style={{padding:16}}>
            <TextInput placeholder="What's happening?" keyboardType="default" value={body} style={{fontSize:20}} onChangeText={text => onChangeText(text)}/>
            {/* <TouchableOpacity style={{justifyContent:'center',alignItems:'center', position:'absolute',bottom:0,left:0,right: 0}}>
                <FontAwesome5 name="photo-video" size={20} />
                <Text>Add Media</Text>
            </TouchableOpacity> */}
        </ScrollView>
    )
}

export default CreatePost


我认为这似乎很简单,我觉得问一个如此基本的问题很愚蠢。我唯一的另一个想法是它与useLayoutEffect 有关,并且当调用 create_post 时,它只能访问初始状态而不是更新状态。如果有人对我做错了什么有任何想法,那就太好了。蒂亚!

编辑

发布后不久,我决定看看如果我让 useLayoutEffect 检查我的 body 变量中的更新会发生什么。果然,帖子的正文按原样通过了。

useLayoutEffect(() => {
        navigation.setOptions({
            title: 'New Post',
            headerRight: () => (
                <Button style={{marginRight:40,fontSize:20}} title="Post" textColor="#0d00ff" onPress={create_post} />
            )
        })
    },[body])

但我还是想知道这是为什么?为什么 onChangeText 没有按照 react 文档中的说明设置我的 body 变量?

【问题讨论】:

  • 因为create_post函数只有在useLayoutEffect中声明时才获取初始状态变量,没有依赖。所以为了让 create_post 函数获得你需要的状态,你必须通过 useEffect(() => { ..etc },[body]) 重新渲染它

标签: javascript react-native react-hooks


【解决方案1】:

你也可以这样做。

useLayoutEffect(() => {
    navigation.setOptions({
        title: 'New Post',
    })
 },[])

useEffect(() => {
    navigation.setOptions({
        headerRight: () => (
            <Button style={{marginRight:40,fontSize:20}} title="Post" textColor="#0d00ff" onPress={create_post} />
        )
 },[body])

这样只会重新渲染按钮

【讨论】:

  • 在这种情况下使用 useLayoutEffect 和 useEffect 感觉是多余的。那么为什么不把所有东西都放在 useEffect 中呢?另外不会将body放在useEffect中重新渲染组件吗?
  • 冗余?不。这种方式告诉我们,标题的权利取决于变量的变化。不是整个导航选项。但这是你的选择。
  • 好吧,这更有意义。抱歉,使用这两种方法而不是其中一种似乎有点过头了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-01
  • 2019-10-29
  • 1970-01-01
  • 1970-01-01
  • 2021-03-22
相关资源
最近更新 更多