状态改变后反应不渲染列表
React not rendering list after the state is changed
我正在创建一个简单的跟踪器来记录所有完成的活动。这是我的第一个反应项目。我创建了三种状态,一种用于存储所有项目(状态名称为列表),一种用于待处理项目(状态名称为待定),一种用于完成项目(状态名称为已完成)。这些项目有一个按钮,单击该按钮会将其标记为完成状态,反之亦然。它正在完全渲染主列表的项目。但对于其他两个,它没有渲染。当我检查 React 开发人员工具时,它工作正常,即它正在添加到待处理列表或完成列表中。但它不是在屏幕上编译它们。列表中已经填满了项目。为了以防万一,我添加了所有代码。
function Filters(props){
const [completed, setCompleted] = useState([]);
const [pending, setPending] = useState([]);
const [state, setState] = useState("None");
const [list,setList] = useState([]);
function viewState(){
setState("View-all");
}
//it is getting the clicked item id and marking it complete in main list
function markComplete(id){
list.map((items,index)=>{
if(index===id){
if(items.done===true)
items.done = false;
else{
items.done=true;
}
}
})
}
//i am simply scanning the main list and the items which are pending will be added to this list. //this happens whenever the person click on pending button
function pendingState(){
setState("pending-all");
setPending([]);
list.map(items=>{
if(items.done!==true){
setPending(prev=>{
return [...prev,items];
})
}
})
}
function completedState(){
setState("completed-all");
setCompleted([]);
list.map(items=>{
if(items.done===true){
setCompleted(prev=>{
return [...prev,items];
})
}
})
}
return (
<div>
<div className="input-section">
<Note setList={setList} />
</div>
<button type="button" onClick={viewState} >View All</button>
<button type="button" onClick={completedState}>Completed</button>
<button type="button" onClick={pendingState}>Pending</button>
<div>
{
(()=>{
if(state==="View-all")
{
return (
<div>
<h1>Working {completed}</h1>
{(list).map((items,index)=>
{
return (
<Excercise
key={index}
id={index}
title={items.name}
list={props.list}
setList={props.setList}
content={items.desp}
markComplete={markComplete}
/>
)
})}
</div>
)
}
else if(state==="completed-all")
{
return (
<div>
{completed.map((items,index)=>{
<Excercise
key={index}
id={index}
title={items.name}
list={props.list}
setList={props.setList}
content={items.desp}
markComplete={markComplete}
/>
})}
</div>
)
}
})()
}
</div>
</div>);
}
请帮忙。谢谢。
嗨@DREW
函数代码:
function markComplete(id){
setList(lists=>{
lists.map(item=>{
return item.id===id ?{...item,done: !item.done} : (item);})
}
)
}
当我使用它而不是
const markComplete = (id) => {
setList((list) =>
list.map((item) =>
item.id === id
? {
...item,
done: !item.done
}
: item
)
);
};
显示“无法读取未定义的属性(读取 'filter')”
两者不一样。如果不是,我做错了什么。不好意思打扰了这么多次,我刚开始用react。
尝试在useEffect
中添加依赖
在此函数中,您正在改变一个状态,因此您需要使用 setState 函数,在本例中为 setList()。
function markComplete(id){
list.map((items,index)=>{
if(index===id){
if(items.done===true)
items.done = false;
else{
items.done=true;
}
}
})
}
因此,实现此功能的更好方法可能是,请记住,每当您需要更新状态时,您不想直接更改状态,相反,您应该制作一个副本并将状态设置为该副本
function markComplete(id){
const newList = [...list];
newList.map((items,index)=>{
if(index===id){
if(items.done===true)
items.done = false;
else{
items.done=true;
}
}
}
setList(newList)
}
你的应用没有更新的原因是因为当你的状态改变时反应不是re-rendering它再次。
所以使用useEffect
,有很多钩子可以根据需要使用。
试试把这行代码
useEffect( ( ) => {
console.log( 'Check console' );
}, [ dependency_here ] );
在dependency_here
中尝试逐一添加state
、completed
、pending
,然后查看结果。
您还可以添加多个依赖项,例如 [ state, pending, etc.. ]
;
自己尝试一下就会理解得更快。
希望提示对您有所帮助!
我认为你把事情复杂化了一点。您只需要一个数组来存储练习,“待定”和“完成”状态很容易从 list
状态和 state
过滤器状态值中导出。
问题
markComplete
回调正在改变 list
状态。更新 list
状态时,不仅需要新的数组引用,而且正在更新的元素也需要新的元素对象引用。
- 使用较差的布尔比较来设置布尔值。您可以切换布尔值或将值设置为布尔表达式的结果。
- 使用
viewState
、pendingState
和 completedState
处理程序来简单地设置过滤器值,然后通过添加内联 filter
在渲染时派生计算状态功能。
- 使用练习
id
属性 作为 React 键 和 作为 属性 用于切换已完成的 (done
) 状态。
解决方案
function Filters(props) {
const [state, setState] = useState("None");
const [list, setList] = useState([
...
]);
function viewState() {
setState("View-all");
}
function pendingState() {
setState("pending-all");
}
function completedState() {
setState("completed-all");
}
const markComplete = (id) => {
setList((list) =>
list.map((item) =>
item.id === id
? {
...item,
done: !item.done
}
: item
)
);
};
return (
<div>
<div className="input-section">
<Note setList={setList} />
</div>
<button type="button" onClick={viewState}>
View All
</button>
<button type="button" onClick={completedState}>
Completed
</button>
<button type="button" onClick={pendingState}>
Pending
</button>
<div>
{list
.filter((item) => {
if (state === "pending-all") {
return !item.done;
} else if (state === "completed-all") {
return item.done;
}
return true;
})
.map((item) => (
<Excercise
key={item.id}
id={item.id}
done={item.done}
title={item.name}
content={item.desp}
markComplete={markComplete}
/>
))}
</div>
</div>
);
}
我正在创建一个简单的跟踪器来记录所有完成的活动。这是我的第一个反应项目。我创建了三种状态,一种用于存储所有项目(状态名称为列表),一种用于待处理项目(状态名称为待定),一种用于完成项目(状态名称为已完成)。这些项目有一个按钮,单击该按钮会将其标记为完成状态,反之亦然。它正在完全渲染主列表的项目。但对于其他两个,它没有渲染。当我检查 React 开发人员工具时,它工作正常,即它正在添加到待处理列表或完成列表中。但它不是在屏幕上编译它们。列表中已经填满了项目。为了以防万一,我添加了所有代码。
function Filters(props){
const [completed, setCompleted] = useState([]);
const [pending, setPending] = useState([]);
const [state, setState] = useState("None");
const [list,setList] = useState([]);
function viewState(){
setState("View-all");
}
//it is getting the clicked item id and marking it complete in main list
function markComplete(id){
list.map((items,index)=>{
if(index===id){
if(items.done===true)
items.done = false;
else{
items.done=true;
}
}
})
}
//i am simply scanning the main list and the items which are pending will be added to this list. //this happens whenever the person click on pending button
function pendingState(){
setState("pending-all");
setPending([]);
list.map(items=>{
if(items.done!==true){
setPending(prev=>{
return [...prev,items];
})
}
})
}
function completedState(){
setState("completed-all");
setCompleted([]);
list.map(items=>{
if(items.done===true){
setCompleted(prev=>{
return [...prev,items];
})
}
})
}
return (
<div>
<div className="input-section">
<Note setList={setList} />
</div>
<button type="button" onClick={viewState} >View All</button>
<button type="button" onClick={completedState}>Completed</button>
<button type="button" onClick={pendingState}>Pending</button>
<div>
{
(()=>{
if(state==="View-all")
{
return (
<div>
<h1>Working {completed}</h1>
{(list).map((items,index)=>
{
return (
<Excercise
key={index}
id={index}
title={items.name}
list={props.list}
setList={props.setList}
content={items.desp}
markComplete={markComplete}
/>
)
})}
</div>
)
}
else if(state==="completed-all")
{
return (
<div>
{completed.map((items,index)=>{
<Excercise
key={index}
id={index}
title={items.name}
list={props.list}
setList={props.setList}
content={items.desp}
markComplete={markComplete}
/>
})}
</div>
)
}
})()
}
</div>
</div>);
}
请帮忙。谢谢。
嗨@DREW 函数代码:
function markComplete(id){
setList(lists=>{
lists.map(item=>{
return item.id===id ?{...item,done: !item.done} : (item);})
}
)
}
当我使用它而不是
const markComplete = (id) => {
setList((list) =>
list.map((item) =>
item.id === id
? {
...item,
done: !item.done
}
: item
)
);
};
显示“无法读取未定义的属性(读取 'filter')” 两者不一样。如果不是,我做错了什么。不好意思打扰了这么多次,我刚开始用react。
尝试在useEffect
在此函数中,您正在改变一个状态,因此您需要使用 setState 函数,在本例中为 setList()。
function markComplete(id){
list.map((items,index)=>{
if(index===id){
if(items.done===true)
items.done = false;
else{
items.done=true;
}
}
})
}
因此,实现此功能的更好方法可能是,请记住,每当您需要更新状态时,您不想直接更改状态,相反,您应该制作一个副本并将状态设置为该副本
function markComplete(id){
const newList = [...list];
newList.map((items,index)=>{
if(index===id){
if(items.done===true)
items.done = false;
else{
items.done=true;
}
}
}
setList(newList)
}
你的应用没有更新的原因是因为当你的状态改变时反应不是re-rendering它再次。
所以使用useEffect
,有很多钩子可以根据需要使用。
试试把这行代码
useEffect( ( ) => {
console.log( 'Check console' );
}, [ dependency_here ] );
在dependency_here
中尝试逐一添加state
、completed
、pending
,然后查看结果。
您还可以添加多个依赖项,例如 [ state, pending, etc.. ]
;
自己尝试一下就会理解得更快。
希望提示对您有所帮助!
我认为你把事情复杂化了一点。您只需要一个数组来存储练习,“待定”和“完成”状态很容易从 list
状态和 state
过滤器状态值中导出。
问题
markComplete
回调正在改变list
状态。更新list
状态时,不仅需要新的数组引用,而且正在更新的元素也需要新的元素对象引用。- 使用较差的布尔比较来设置布尔值。您可以切换布尔值或将值设置为布尔表达式的结果。
- 使用
viewState
、pendingState
和completedState
处理程序来简单地设置过滤器值,然后通过添加内联filter
在渲染时派生计算状态功能。 - 使用练习
id
属性 作为 React 键 和 作为 属性 用于切换已完成的 (done
) 状态。
解决方案
function Filters(props) {
const [state, setState] = useState("None");
const [list, setList] = useState([
...
]);
function viewState() {
setState("View-all");
}
function pendingState() {
setState("pending-all");
}
function completedState() {
setState("completed-all");
}
const markComplete = (id) => {
setList((list) =>
list.map((item) =>
item.id === id
? {
...item,
done: !item.done
}
: item
)
);
};
return (
<div>
<div className="input-section">
<Note setList={setList} />
</div>
<button type="button" onClick={viewState}>
View All
</button>
<button type="button" onClick={completedState}>
Completed
</button>
<button type="button" onClick={pendingState}>
Pending
</button>
<div>
{list
.filter((item) => {
if (state === "pending-all") {
return !item.done;
} else if (state === "completed-all") {
return item.done;
}
return true;
})
.map((item) => (
<Excercise
key={item.id}
id={item.id}
done={item.done}
title={item.name}
content={item.desp}
markComplete={markComplete}
/>
))}
</div>
</div>
);
}