**
更新:这个问题有一个有效的答案。 非常重要 请注意,即使您的函数中有return语句 在render()中调用,包装整个循环仍然很重要 父母"返回"为了使其在状态上正确呈现 更改。这是状态未更新的另一个常见问题 的正确。
我有以下ClientList组件,它显示了从数据库中检索的客户列表。
下面在Render()函数中,我调用了showList函数,一旦this.props.clientList Reducer被填充,它将显示一个列表。
问题是......如果我直接在Render()方法中调用showList代码,它将显示。
如果我将它放在showList函数中,并调用{this.showList}它不会显示在渲染中。
我也有控制台的屏幕截图,显示列表已经填充。
这种方法不被禁止吗?我看到很多教程教导我们这样做,但它并不适合我。使用此方法返回渲染代码有什么限制?
import Cocoa
// some convenience functions for our dummy callAPI1 & callAPI2
func random(_ range : CountableClosedRange<UInt32>) -> UInt32
{
let lower = range.lowerBound
let upper = range.upperBound
return lower + arc4random_uniform(upper - lower + 1)
}
func randomBool() -> Bool
{
return random(0...1) == 1
}
class Demo
{
// grab the global concurrent utility queue to schedule our work on
let workerQueue = DispatchQueue.global(qos : .utility)
// dummy callAPI1, just pauses and then randomly return success or failure
func callAPI1(_ completion : @escaping (Bool) -> Void) -> Void
{
// do the "work" on workerQueue, which is concurrent so other work
// can be executing, or *blocked*, on the same queue
let pause = random(1...2)
workerQueue.asyncAfter(deadline: .now() + Double(pause))
{
// produce a random success result
let success = randomBool()
print("callAPI1 after \(pause) -> \(success)")
completion(success)
}
}
func callAPI2(_ completion : @escaping (Bool) -> Void) -> Void
{
let pause = random(1...2)
workerQueue.asyncAfter(deadline: .now() + Double(pause))
{
let success = randomBool()
print("callAPI2 after \(pause) -> \(success)")
completion(success)
}
}
func runDemo(_ completion : @escaping (Bool) -> Void) -> Void
{
// We run the demo as a standard async function
// which doesn't block the main thread
workerQueue.async
{
print("Demo starting...")
var isSuccess: Bool = false
let semaphore = DispatchSemaphore(value: 0)
// do the first call
// this will asynchronously execute on a different thread
// *including* its completion block
self.callAPI1
{ (result) in
isSuccess = result
semaphore.signal() // signal completion
}
// we can safely wait for the semaphore to be
// signalled as callAPI1 is executing on a different
// thread so we will not deadlock
semaphore.wait()
if isSuccess
{
self.callAPI2
{ (result) in
isSuccess = result
semaphore.signal() // signal completion
}
semaphore.wait() // wait for completion
}
completion(isSuccess)
}
}
}
Demo().runDemo { (result) in print("Demo result: \(result)") }
// For the Playground
// ==================
// The Playground can terminate a program run once the main thread is done
// and before all async work is finished. This can result in incomplete execution
// and/or errors. To avoid this we sleep the main thread for a few seconds.
sleep(6)
print("All done")
// Run the Playground multiple times, the results should vary
// (different wait times, callAPI2 may not run). Wait until
// the "All done"" before starting next run
// (i.e. don't push stop, it confuses the Playground)
答案 0 :(得分:0)
构造函数中不需要bind
showList
。
删除它,你应该没事。
另外,正如@JayabalajiJ指出的那样,你需要从showList
返回一些东西,否则你将看不到最终的结果。
class ClientList extends React.Component {
constructor() {
super()
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
console.log('click')
}
showList() {
return <button onClick={this.handleClick}>From showList</button>
}
render() {
return (
<div>
<button onClick={this.handleClick}>Click-me</button>
{this.showList()}
</div>
)
}
}
ReactDOM.render(
<ClientList />,
document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
答案 1 :(得分:0)
您应该从showList()方法返回值。截至目前,您正在返回map方法的值,但不是整个showList()方法的值。那是它在页面上没有任何东西 `
showList() {
return (
//removed unnecessary {}
this.props.clientList && Object.keys(this.props.clientList).reverse().map((index,key) => {
return (
<div key={key}>
<div><a onClick={() => this.showProfileBox(this.props.clientList[index].customerId)}>Name: {this.props.clientList[index].firstname} {this.props.clientList[index].lastname}</a><span className="pull-right"><Link to={"/client/" + this.props.clientList[index].customerId}>Edit</Link></span></div>
</div>
);
})
);
}
`