bra*_*ert 29 javascript reactjs
我有一个React类,它将用于获取内容的API.我已经确认数据会回来,但它不会重新渲染:
var DealsList = React.createClass({
getInitialState: function() {
return { deals: [] };
},
componentDidMount: function() {
this.loadDealsFromServer();
},
loadDealsFromServer: function() {
var newDeals = [];
chrome.runtime.sendMessage({ action: "findDeals", personId: this.props.person.id }, function(deals) {
newDeals = deals;
});
this.setState({ deals: newDeals });
},
render: function() {
var dealNodes = this.state.deals.map(function(deal, index) {
return (
<Deal deal={deal} key={index} />
);
});
return (
<div className="deals">
<table>
<thead>
<tr>
<td>Name</td>
<td>Amount</td>
<td>Stage</td>
<td>Probability</td>
<td>Status</td>
<td>Exp. Close</td>
</tr>
</thead>
<tbody>
{dealNodes}
</tbody>
</table>
</div>
);
}
});
Run Code Online (Sandbox Code Playgroud)
但是,如果我添加debugger
如下所示,newDeals
填充,然后一旦我继续,我看到数据:
loadDealsFromServer: function() {
var newDeals = [];
chrome.runtime.sendMessage({ action: "findDeals", personId: this.props.person.id }, function(deals) {
newDeals = deals;
});
debugger
this.setState({ deals: newDeals });
},
Run Code Online (Sandbox Code Playgroud)
这就是所谓的交易清单:
var Gmail = React.createClass({
render: function() {
return (
<div className="main">
<div className="panel">
<DealsList person={this.props.person} />
</div>
</div>
);
}
});
Run Code Online (Sandbox Code Playgroud)
Sti*_*itt 59
我想补充一点非常简单,但是很容易犯错误的写作:
this.state.something = 'changed';
Run Code Online (Sandbox Code Playgroud)
...然后不理解为什么它不是渲染和谷歌搜索并进入这个页面,只是意识到你应该写:
this.setState({something: 'changed'});
Run Code Online (Sandbox Code Playgroud)
如果您使用setState
更新状态,则React仅触发重新渲染.
Tsa*_*v96 16
要正确更新状态,您不应改变数组。您需要创建数组的副本,然后使用复制的数组设置状态。
const [deals, setDeals] = useState([]);
function updateDeals(deal) {
const newDeals = [...deals]; // spreading operator which doesn't mutate the array and returns new array
newDeals.push(deal);
// const newDeals = deals.concat(deal); // concat merges the passed value to the array and return a new array
// const newDeals = [...deals, deal] // directly passing the new value and we don't need to use push
setDeals(newDeals);
}
Run Code Online (Sandbox Code Playgroud)
Mic*_*ley 14
那是因为响应chrome.runtime.sendMessage
是异步的; 这是操作的顺序:
var newDeals = [];
// (1) first chrome.runtime.sendMessage is called, and *registers a callback*
// so that when the data comes back *in the future*
// the function will be called
chrome.runtime.sendMessage({...}, function(deals) {
// (3) sometime in the future, this function runs,
// but it's too late
newDeals = deals;
});
// (2) this is called immediately, `newDeals` is an empty array
this.setState({ deals: newDeals });
Run Code Online (Sandbox Code Playgroud)
当您使用调试器暂停脚本时,您将给予扩展时间来调用回调; 当你继续时,数据已经到达,它似乎工作.
要解决此问题,您需要setState
在Chrome扩展程序返回数据后进行通话:
var newDeals = [];
// (1) first chrome.runtime.sendMessage is called, and *registers a callback*
// so that when the data comes back *in the future*
// the function will be called
chrome.runtime.sendMessage({...}, function(deals) {
// (2) sometime in the future, this function runs
newDeals = deals;
// (3) now you can call `setState` with the data
this.setState({ deals: newDeals });
}.bind(this)); // Don't forget to bind(this) (or use an arrow function)
Run Code Online (Sandbox Code Playgroud)
[编辑]
如果这对您不起作用,请查看此问题的其他答案,其中说明了您的组件可能未更新的其他原因.
小智 13
我的情况有点不同。而且我认为很多像我这样的新手都会被难住 - 所以在这里分享。
我的状态变量是一个由 useState 管理的 JSON 对象数组,如下所示:
const [toCompare, setToCompare] = useState([]);
Run Code Online (Sandbox Code Playgroud)
但是,当使用 setToCompare 更新 toCompare 时,如下面的函数所示 - 不会触发重新渲染。并将其移动到不同的组件也不起作用。只有当其他一些事件会触发重新渲染时 - 更新的列表才会出现。
const addUniversityToCompare = async(chiptoadd) =>
{
var currentToCompare = toCompare;
currentToCompare.push(chiptoadd);
setToCompare(currentToCompare);
}
Run Code Online (Sandbox Code Playgroud)
这是我的解决方案。基本上 - 分配数组是复制引用 - 并且反应不会将其视为更改 - 因为数组的引用没有被更改 - 只有其中的内容。所以在下面的代码中 - 只是使用切片复制了数组 - 没有任何更改 - 并在 mods 之后将其分配回来。工作得很好。
const addUniversityToCompare = async (chiptoadd) => {
var currentToCompare = toCompare.slice();
currentToCompare.push(chiptoadd);
setToCompare(currentToCompare);
}
Run Code Online (Sandbox Code Playgroud)
希望它可以帮助像我这样的人。任何人,如果您觉得我错了,请告诉我 - 或者有其他方法。
提前致谢。
就我而言,我调用this.setState({})
正确,但我的函数没有绑定到这个,所以它不起作用。添加.bind(this)
到函数调用或this.foo = this.foo.bind(this)
在构造函数中执行修复它。
归档时间: |
|
查看次数: |
71524 次 |
最近记录: |