在我的代码中,我替换这些值
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 打字稿的初学者,所以我不知道如何解决这个问题,请给我一个解决这个问题的解决方案
虽然将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