当前位置: 首页 > 知识库问答 >
问题:

React:如何更改道具值

萧阳波
2023-03-14

在我的代码中,我替换这些值

const [items, setItem] = useState<string[]>([]);
const [value, setValue] = useState('')
const [error, setValue]= useState('')

到这个

类型道具={项目?:字符串[],值?:字符串,错误?:字符串}

然后更改以下设置项,设置值,设置值,这会导致以下错误

import React, { useRef, useState } from "react";
import ReactDOM from "react-dom";
import Chip from "@material-ui/core/Chip";
import TextField from "@material-ui/core/TextField";

type Props = {
  items?: string[],
  value?: string,
  error?: string
}

export const TagActions = (props:Props) => {
    const { items, value, error } = props;

    // const [items, setItem] = useState<string[]>([]);
    // const [value, setValue] = useState('')
    // const [error, setError]= useState('')
    
    const divRef = useRef<HTMLDivElement>(null)

    const handleDelete = (item:any) => {
        console.log("handleDelete", item)
        const result = items?.filter(i => i !== item)
        setItem(result)
      };
    
    const handleItemEdit = (item:any) =>{
        console.log("handleItemEdit", item)
        const result = items?.filter(i => i !== item)
        
        items = result    // setItem(result)
        value = item     // setValue(item)

        console.log("value", value)
        
    };

    const handleKeyDown = (evt:any) => {
        if (["Enter", "Tab", ","].includes(evt.key)) {
          evt.preventDefault();

          var test = value?.trim();
    
          if (test && isValid(test)) {
            items?.push(test)
            setValue("")
           
          }
        }
    };

    const isValid = (email:any)=> {
        let error = null;
    
        if (isInList(email)) {
          error = `${email} has already been added.`;
        }
    
        if (!isEmail(email)) {
          error = `${email} is not a valid email address.`;
        }
    
        if (error) {
            setError(error);
    
          return false;
        }
    
        return true;
    }

    const isInList = (email:any)=> {
        return items?.includes(email);
      }
    
    const isEmail = (email:any)=> {
        return /[\w\d\.-]+@[\w\d\.-]+\.[\w\d\.-]+/.test(email);
    }

    const handleChange = (evt:any) => {
        setValue(evt.target.value)
        // setError("")
        
    };

    const handlePaste = (evt:any) => {
        evt.preventDefault();
    
        var paste = evt.clipboardData.getData("text");
        var emails = paste.match(/[\w\d\.-]+@[\w\d\.-]+\.[\w\d\.-]+/g);
    
        if (emails) {
          var toBeAdded = emails.filter((email:any) => !isInList(email));
            
            setItem(toBeAdded)
        
        }
    };
    


    return (
        <>
          <div>
          <TextField id="outlined-basic" variant="outlined"
          InputProps={{
            startAdornment: items?.map(item => (
              <Chip
                key={item}
                tabIndex={-1}
                label={item}
                onDelete={() => handleDelete(item)}
                onClick={() => handleItemEdit(item)}
              />
            )),
  
          }}
            ref={divRef}
            value={value}
            placeholder="Type or paste email addresses and press `Enter`..."
            onKeyDown={(e) => handleKeyDown(e)}
            onChange={(e) => handleChange(e)}
            onPaste={(e) => handlePaste(e)}
          />
          </div>
  
          {error && <p className="error">{error}</p>}
        </>
      );
}

我是 react 打字稿的初学者,所以我不知道如何解决这个问题,请给我一个解决这个问题的解决方案

共有1个答案

盛承
2023-03-14

虽然将const更改为let可能会修复控制台中的即时错误,但我怀疑这会给您带来所需的行为。

这里的主要问题是您正在改变props的值,通常您不应该这样做。Props用于将有状态数据从父组件向下传递到子组件。如果您希望从子组件更新此数据的状态,您也应该使用props传递一个更新函数。下面通过实现删除项函数(没有打字稿,但希望它能传达这个想法)来说明我的意思:

const ParentComponent = () => {
  const [items, setItems] = useState(["item1", "item2", "item3"])
  
  const deleteItem = (itemToDelete) => {
    //here we use the functional update form of setState which is good practise when the new state depends on the old state
    setItems((items) => items.filter((item) => item!==itemToDelete))
  }
  
  return <ChildComponent items={items}, onDeleteItem={deleteItem} />
}
const ChildComponent = ({items, onDeleteItem}) => {

  //e.g. to delete item2 call
  onDeleteItem("item2")
}

这是React中比较令人困惑的模式之一,但是让你的头脑清醒是非常重要的。只有声明状态的组件才应该真正更新该状态——因为它是您唯一可以访问setState函数的地方。

 类似资料:
  • 我有问题的反应形式和管理的状态适当。我在一个表单中有一个时间输入字段(在一个模态中)。初始值在中设置为状态变量,并从父组件传入。这本身就很好用。 当我想通过父组件更新默认的start_time值时,问题就来了。更新本身通过在父组件中发生。但是,在我的表单中,默认的start_time值从不更改,因为它只在中定义过一次。 我尝试使用通过强制更改状态,这确实起到了作用,但给了我错误。 所以我的问题是,

  • 请考虑以下示例: 我希望将值传递到中,作为哑输入组件的道具。然而,它从不重新呈现它。

  • 问题内容: 我正在尝试将表示性组件与容器组件分开。我有一个和一个。容器负责触发redux操作,以根据当前用户获取适当的网站。 问题是在最初呈现容器组件之后,异步获取了当前用户。这意味着容器组件不知道它需要重新执行其函数中的代码,该代码将更新数据以发送到。我认为我需要在其props(user)之一更改时重新渲染容器组件。如何正确执行此操作? 问题答案: 您必须在方法中添加条件。 该示例用于比较对象。

  • 我试图将表示组件与容器组件分开。我有一个和一个。容器负责触发redux操作,以基于当前用户获取适当的站点。 问题在于,在容器组件最初呈现之后,当前用户是异步获取的。这意味着容器组件不知道需要在其函数中重新执行代码,该函数将更新数据以发送到。我想当容器组件的一个道具(用户)发生变化时,我需要重新渲染它。如何正确地执行此操作?

  • 问题内容: 什么是对React组件prop更新进行单元测试的正确方法。 这是我的测试装置; 这可以正常工作,并且测试通过了,但是显示了反应警告消息 我要测试的只是属性的更新,而不是使用其他属性创建元素的新实例。有没有更好的方法来执行此属性更新? 问题答案: AirBnB的酶库为这个问题提供了一个优雅的解决方案。 它提供了一个setProps方法,可以在浅包装或jsdom包装上调用该方法。

  • 问题内容: 有没有一种方法可以检查里面的道具发生了变化(没有在其他地方存储旧道具)? 即 问题答案: 请注意,该功能现已 弃用 。引用官方文件: 如果仅当属性更改时才用于重新计算某些数据,请改用备忘录助手。 这是指您的内部检查避免不必要地多次重新计算相同内容的情况。在链接的博客文章中,它建议将昂贵功能的结果缓存起来,以便可以查找它,而不是重新计算它。可以使用诸如memoize- one之 类的助手

  • 我有以下结构: ChildComponent只是呈现值:

  • 我正在制作一个paginate组件,我在传递给这个paginate组件的道具上遇到了问题。元素道具正在自动更新,所以我不能使用componentWillReceiveProps来更新我的组件。 下面是我的父组件呈现和对Paginate组件的回调: 下面是我的分页组件: 代码在post advisions之后更新,但是:componentWillReceiveProps(nextProps){con