【发布时间】:2020-05-30 17:58:58
【问题描述】:
编辑:由于代码片段不会重现错误 - 这是 github 存储库的链接:(代码远未完成)
https://github.com/altruios/clicker-game
我现在已经在两台计算机上运行它 - 两者都具有代码片段未显示的相同行为。
//interestingly enough, this works just fine, where the same code I run locally has the doubling.
//when I comment out ALL other code except for this code I STILL get the error locally
//at this point the only difference is import export of components... here they are in one file.
//below is original code from file (
/*
FILE::::Clicker.js
import React from 'react';
function Clicker(props)
{
return(
<div>
{props.name}
<button
name={props.name}
onClick={props.HandleClick}
data-target={props.subjectsOfIncrease}>
{props.name} {props.value}
</button>
</div>
)
}
export default Clicker;
FILE:: Resouce.js
import React from 'react';
function Resource(props)
{
return(
<div>
{props.name} and {props.amount || 0}
</div>
)
}
export default Resource;
*/
//besides the import/export and seprate files - code is the same. it works in here, does not work locally on my machine.
const gameData = {
clickerData: [{
name: "grey",
subjectsOfIncrease: ["grey"],
isUnlocked: true,
value: 1
}],
resourceData: [{
name: "grey",
resouceMax: 100,
isUnlocked: true,
changePerTick: 0,
counterTillStopped: 100,
amount: 0
}]
}
class App extends React.Component {
constructor() {
super();
this.state = {
resources: gameData.resourceData,
clickers: gameData.clickerData
};
this.gainResource = this.gainResource.bind(this);
}
gainResource(event) {
console.count("gain button");
const name = event.target.name;
this.setState((prevState) => {
const newResources = prevState.resources.map(resource => {
if (resource.name === name) {
resource.amount = Number(resource.amount) + 1 //Number(prevState.clickers.find(x=>x.name===name).value)
}
return resource;
});
console.log(prevState.resources.find(item => item.name === name).amount, "old");
console.log(newResources.find(item => item.name === name).amount, "new");
return {
resources: newResources
}
});
}
render() {
const resources = this.state.resources.map(resourceData => {
return (
<Resource
name = {resourceData.name}
resouceMax = {resourceData.resourceMax}
isUnlocked = {resourceData.isUnlocked}
changePerTick = {resourceData.changePerTick}
counterTillStopped = {resourceData.countTillStopped}
amount = {resourceData.amount}
key = {resourceData.name}
/>
)
})
const clickers = this.state.clickers.map(clickerData => {
return (
<Clicker
name = {clickerData.name}
HandleClick = {this.gainResource}
value = {clickerData.amount}
key = {clickerData.name}
/>
)
})
return (
<div className = "App" >
{resources}
{clickers}
</div>
)
}
}
function Resource(props) {
return <div > {props.name} and {props.amount || 0} </div>
}
function Clicker(props) {
return (
<div > {props.name}
<button name = {props.name} onClick = {props.HandleClick}>
{props.name} {props.value}
</button>
</div>
)
}
const root = document.getElementById('root');
ReactDOM.render( <App / >,root );
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
所以我正在构建一个点击游戏来学习反应,我不明白为什么这段代码会这样:
在主应用中我有这个功能:
gainResource(event)
{
console.count("gain button");
const name = event.target.name;
this.setState( (prevState)=>
{
const newResources = prevState.resources.map(resource=>
{
if(resource.name === name)
{
resource.amount = Number(resource.amount) + 1 //Number(prevState.clickers.find(x=>x.name===name).value)
}
return resource;
});
console.log(prevState.resources.find(item=>item.name===name).amount, "old");
console.log(newResources.find(item=>item.name===name).amount, "new");
return {resources: newResources}
});
}
console.count 运行一次......但我得到了 2 对“新旧”对。好像 setState 在这个只运行一次的函数中运行了两次?
console.output 是:
App.js:64 gain button: 1
App.js:76 1 "old"
App.js:77 1 "new"
App.js:76 2 "old"
App.js:77 2 "new"
所以看起来函数运行了一次。但是设置状态正在运行两次?
症状是它增加了 2。而且数量的初始状态是 0,而不是 1,如 gamedata.json 中所示
resourceData:
[
{
name:"grey",
resouceMax:100,
isUnlocked:true,
changePerTick:0,
counterTillStopped:100,
amount:0
},{etc},{},{}],
clickerData:
[
{
name:"grey",
subjectsOfIncrease:["grey"],
isUnlocked:true,
value:1
},{etc},{},{}]
我不认为我要处理的其余代码与这种行为有关,但我还不知道反应,所以我不知道我错过了什么:但这就是我正在生成点击器按钮:
const clickers = this.state.clickers.map(clickerData=>
{
return(
<Clicker
name={clickerData.name}
HandleClick = {this.gainResource}
value = {clickerData.amount}
key={clickerData.name}
/>
)
})
在 clicker.js 功能组件中,我只是返回这个:
<div>
{props.name}
<button name={props.name} onClick={props.HandleClick}>
{props.name} {props.value}
</button>
</div>
该函数在构造函数中绑定到 this...我不明白为什么 this 在一个调用一次的函数中运行 setState 两次。
我也试过了:
<div>
{props.name}
<button name={props.name} onClick={()=>props.HandleClick}> //anon function results in no output
{props.name} {props.value}
</button>
</div>
【问题讨论】:
-
有趣。您是否会使用可运行的minimal reproducible example 来更新您的问题,使用 Stack Snippets(
[<>]工具栏按钮)演示问题。 Stack Snippets 支持 React,包括 JSX; here's how to do one。这将帮助人们看到问题并帮助他们帮助你。 -
添加了代码片段:但是这并没有在代码片段中重现......这让我发疯了我已经注释掉了所有其他代码,除了该代码片段中的内容和我的机器上的行为保持不变(双重调用),但它在代码片段中工作正常继续撕掉头发感谢代码片段的提示......第一次使用它......到目前为止我唯一线索是代码片段和我的代码之间的区别:这是因为代码被分成几个文件以进行组织,而不是像代码片段中那样的一个主文件......仍然不知道问题是什么。 ..
-
添加一个指向 git-hub 的链接,以便人们可以在他们的机器上本地运行它 - 看看问题可能是什么......因为代码片段没有重现错误。
标签: javascript reactjs setstate