- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我花了几天时间查看类似的帖子,但没有解决方案。由于某种原因,当我使用 setPostState(myState.posts);
时,它不会重新渲染组件。
我正在使用 react ^16.10.2
下面是我的代码:
import React, {useState, useCallback} from 'react';
import {withStyles, makeStyles} from '@material-ui/core/styles';
import {Paper, TableRow, TableHead, TableCell, TableBody, Table, Badge, Fab} from '@material-ui/core'
import {myState} from '../../PubSub/pub-sub'
import ThumbUpIcon from '@material-ui/icons/ThumbUp';
import ThumbDownIcon from '@material-ui/icons/ThumbDown';
const StyledTableCell = withStyles(...))(TableCell);
const StyledTableRow = withStyles(...))(TableRow);
const useStyles = makeStyles(theme => (...));
export default props => {
console.log("++++++++++++++++Render Body+++++++++++++++++++++");
const classes = useStyles();
let [postState, setPostState] = useState(myState.posts);// why does setPostState not update badge count???? or re-render component???
let upVote = (id) => {
let objIndex = myState.posts.findIndex((obj => obj.id == id));
return (
<Fab key={"upVote4309lk" +id} color="primary" aria-label="add" className={classes.fab}
onClick={() => {
myState.posts[objIndex].up_vote++;
setPostState(myState.posts);//why does this not update badge count???? or re-render component???
}}>
<Badge key={"Ubadge"+objIndex} className={classes.margin} badgeContent={postState[objIndex].up_vote} color="primary"><
ThumbUpIcon> </ThumbUpIcon>
</Badge>
</Fab>
)
};
let downVote = (id) => {
let objIndex = myState.posts.findIndex((obj => obj.id == id));
return (
<Fab key={"downVote0940v" + id} color="primary" aria-label="add" className={classes.fab}
onClick={() => {
myState.posts[objIndex].down_vote++;
setPostState(myState.posts);//why does this not update badge count???? or re-render component???
}}>
<Badge className={classes.margin} badgeContent={myState.posts[objIndex].down_vote} color="primary"><
ThumbDownIcon> </ThumbDownIcon>
</Badge>
</Fab>
)
};
function filter(name) {
return name.toLowerCase().includes(props.searchData.title.toLowerCase());
}
function createData(title, description, user, up_votes, down_votes, id) {
if (filter(title, description, user, up_votes, down_votes)) {
return (
<StyledTableRow key={id + "tableKey"}>
<StyledTableCell>{title}</StyledTableCell>
< StyledTableCell>{description}</StyledTableCell>
<StyledTableCell>{user}</StyledTableCell>
<StyledTableCell>{upVote(id)}</StyledTableCell>
<StyledTableCell>{downVote(id)}</StyledTableCell>
</StyledTableRow>
)
}
}
const rows = myState.posts.map(
obj => createData(obj.title, obj.description, obj.user, obj.up_votes, obj.down_votes, obj.id)
);
return (
<Paper className={classes.root}>
<Table className={classes.table} aria-label="customized table">
<TableHead>
<TableRow>
<StyledTableCell>Title</StyledTableCell>
<StyledTableCell>Description</StyledTableCell>
<StyledTableCell>User</StyledTableCell>
<StyledTableCell>Up Votes</StyledTableCell>
<StyledTableCell>Down Votes</StyledTableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map(row => (row))}
</TableBody>
</Table>
</Paper>
);
}
任何帮助都会很棒,谢谢!
最佳答案
在 React 中,组件仅在 state
发生变化时重新渲染,即 prevState
!== currentState
无论是基于类的还是函数式的成分。在您的情况下,您正在调用 setPosts 但它不会更改状态,因为您在设置状态时分配了相同的对象 myState.posts
。 React 不会对对象执行深度相等性检查,而只是比较处于某种状态的对象的引用。在您的情况下,当您发生变异时,引用永远不会改变,并且在调用 setPosts 后 prevState
保持等于 newState
。
为了避免这个问题,在 React 中使用对象/数组设置状态时,您需要确保分配一个新的引用。因此,比较 prevState
和 currState
返回 false。有关更多详细信息,请参阅相等性检查示例
访问和设置状态的正确方法:
// Set the initial value using myState.posts and then use the variable
// postState to access the posts and not myState.posts
const [postState, setPostState] = useState(myState.posts)
const makeUpVote = (objIndex) => {
// Make local variable posts to change and set posts while
// using spread operator to make sure we get a new array created instead
// of pointing to the same array in memory
const posts = [...postState]
posts[objIndex].up_vote++
setPostState(posts)
}
let upVote = id => {
// use postState to access instead of myState.posts
let objIndex = postState.findIndex(obj => obj.id == id)
return (
<Fab
// I would recommend creating separate functions to handle this
// instead of writing them inline.
onClick={() => makeUpVote(objIndex)}
></Fab>
)
}
平等检查示例:
// This snippet is just to give you an idea of mutation
const posts = [{id: 1, upvote: 0}, {id: 2, upvote: 0}]
const posts2 = posts
// using spread operator from ES6 to assign a new array with similar values to posts3
const posts3 = [...posts]
posts[0].upvote++
posts3[0].upvote++
// This statement will return true because posts and posts2 have
// the same address in memory (reference) even though we just
// changed posts variable.
// If we set posts2 in state and initial state was posts
// component will NOT re-render
console.log(posts === posts2)
// This will return false because we assigned a new object
// to posts3 using spread operator even though values are same
// If we set posts3 in state an initial state was posts
// component will re-render
console.log(posts === posts3)
// Now another thing to notice is that spread operator does not
// perform deep cloning and therefore the object at index 0 in
// posts has the same reference to object at index 0 in posts 3
// therefore we get upvote = 2
console.log("Posts: ", posts)
console.log("Posts3: ", posts3)
关于reactjs - 在 onClick 函数内调用更新函数时 useState 不会重新渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58784464/
我有几个系统使用 docker-compose 并且没有问题。 但是,我在这里有一个“向下”根本不做任何事情的地方。 'up'虽然完美。这是在 MacOS 上。 该项目的昵称是“ Storm ”,脚本
解释起来确实很奇怪,所以就这样...... 我正在从 phpmyadmin 获取包含未转义单引号的数据。我正在尝试转换'至'通过使用Content-Type: text/html;在 php
伙计们?在这里需要一些帮助。我使用委托(delegate)协议(protocol)将一些字符串从“第二个 View Controller ”传回给它的前一个。 我的数组附加了我在委托(delegate
我有以下 eval() 东西: c = Customer() eval("c.name = row.value('customer', '{c}')".format(c=column_name), {
我写了这个测试类: @ContextConfiguration(locations = { "classpath:/test/BeanConfig.xml" }) public class Candi
我这样写代码: @ContextConfiguration(locations = { "classpath:/test/BeanConfig.xml" }) @RunWith(SpringJUnit
假设我更改了文件,然后进行 pull 。 Git 会报错,因为本地仓库还没有保存,将被覆盖。如果我然后删除该添加并使文件与以前相同(与远程 repo 相同),那么会发生 pull 吗? 最佳答案 是的
我正在阅读《Java for Dummies》一书,但遇到了问题。我不明白为什么 @Override 不起作用。我确信这与我的代码有关,因为我之前已经获得了一个多态数组来使用覆盖,但它对我来说太简单了
我从我的项目中提取了这段代码,因为我试图找到我犯的一个错误,该错误使我的 BeginStoryboard 无法自行停止。我尽可能地简化了代码,但仍然没有发现问题。你认为它可能是什么?
这个问题在这里已经有了答案: Difference between char[] and char * in C [duplicate] (3 个答案) 关闭 7 年前。 我想我知道自己问题的答案,
我一直在使用 java 的 Scanner 类时遇到问题。我可以让它很好地读取我的输入,但问题是当我想要输出一些东西时。给定多行输入,我想在完全读取所有输入后只打印一行。这是我用来读取输入的代码:
对于这个问题,我已经用最简单的术语表达了这一点。 如果元素被点击,'active'类被添加到元素,'active'类从其他元素中移除。 但是,如果该元素是“事件的”并且它被第二次单击,则“事件”类不应
这会在桌面上创建一个新文件夹,但不会将文件夹 .pfrom 的内容 move 到文件夹 .pTo。 int main() { SHFILEOPSTRUCT sf = {0}; TCHA
我有一个关于多线程调试 DLL (/MDd) 和多线程调试 (/MTd) 设置的问题。它们之间的区别很明显:一个是使用动态库,一个是使用静态库。当我使用/MDd 编译我的程序时,一切都进行得很好。但是
我的问题是,如果我在页面加载时创建一个克隆变量,jQuery 只会 append 它一次。奇怪! Click to copy This is an element! $(document)
所以...我是一个开发 django 应用程序的新手,但是当我尝试通过 virtualbox heroku 运行 heroku run python manage.py syncdb 时,它一直在下面
我在 Spring Boot 初始化时遇到了问题。我在一个简单的 Spring Boot 项目中有这个结构。 com.project.name |----App.java (Annoted with
我在 www.7hermanosmx.com/menu.php 页面上有以下代码 - 一切正常,除了黄色框(类 menuholder)应该每行三个相互 float 。他们坚决拒绝这样做!我知道我做错了
我正在尝试在我正在构建的小型网站上添加一个下拉菜单。出于某种原因,我可以获得我想要向下滑动到 fadeOut() 的 div 并执行其他类似的操作,但我无法将它获取到 slideDown()。我不知道
我有一个不能正确 float 的 div。当您切换可见性时,它会覆盖一些当前文本,但我可以稍后移动它。只是好奇为什么它不能正确 float ! Simple Tabs with CSS &am
我是一名优秀的程序员,十分优秀!