我有这个组件,我想在api电话后重新投降。我无法弄清楚为什么在api调用getWinks之后,winks-count会更新但不会在视图上更新,除非我刷新。我不应该使用this.forceUpdate()。请提出建议,欢迎任何批评。
export default class Winks extends Component {
constructor (props) {
super(props)
this.insertDecimal = this.insertDecimal.bind(this)
this.state = ({
user:cookie.load('user',
)})
console.log(this.state)
this.httpHandler = axios.create({
baseURL: 'localhost:3000',
headers: {
'Authorization': this.state.user.token
}
})
}
insertDecimal(num) {
var num = (num / 100).toFixed(2);
return '$' + num
}
getWinks (itemId) {
this.httpHandler.post("/users/" + this.state.user.id + "/winks", {
user_id:this.state.user.id,
wink: {
product_id:itemId
}
}).then(function (response){
this.forceUpdate()
}.bind(this))
}
render () {
var listItems = this.props.products.map(function(item, index,) {
var wink = item.attributes
if (index % 5 ===0) {
return (
<Col lg={2} md={4} sm={4} xs={6}>
<div className="item">
<img className='img-responsive' src={wink["image-url"]}></img>
<div className="item-meta">
<span className="name">{wink.name}</span>
<span className="site"> Bloomingdales.com</span>
<div className="rate">
<span className="old">{this.insertDecimal(wink.price)}</span>
<span className="new">{this.insertDecimal(wink["sale-price"])}</span>
</div>
<div className="like">
<i onClick={()=>this.getWinks(item.id)} className="fa fa-heart"></i>
<span>{wink["winks-count"]}</span>
</div>
</div>
</div>
</Col>
)
}
else {
return (
<Col lg={2} md={4} sm={4} xs={6}>
<div className="item">
<img className='img-responsive' src={wink["image-url"]}></img>
<div className="item-meta">
<span className="name">{wink.name}</span>
<span className="site"> Bloomingdales.com</span>
<div className="rate">
<span className="old">{this.insertDecimal(wink.price)}</span>
<span className="new">{this.insertDecimal(wink["sale-price"])}</span>
</div>
<div className="like">
<i onClick={()=>this.getWinks(item.id)} className="fa fa-heart"></i>
<span>{wink["winks-count"]}</span>
</div>
</div>
</div>
</Col>
)
}
}.bind(this));
return (
<Row className="item-row">
{listItems}
</Row>
)
}
}
父组件:
export default class AllItems extends Component {
constructor () {
super()
this.state=({ user: cookie.load('user')})
this.httpHandler = axios.create({
baseURL: 'localhost:3000',
headers: {
'Authorization': this.state.user.token
}
})
}
componentWillMount() {
this.httpHandler('/products/')
.then(function (response) {
this.setState({ winks: response.data.data})
}.bind(this))
}
render() {
return (
<Grid>
<div className="item-wrapper">
<Row>
<h1 className="text-center">All Items</h1>
</Row>
<Row>
<Col xs={2}>
<div className="item-sidebar-wrapper">
<div className="sort">
<Sort />
</div>
<div className="category">
<Category />
</div>
<div className="price">
<Price />
</div>
<div className="size">
<Size />
</div>
<div className="color">
<Color />
</div>
<div className="brand">
<Brand />
</div>
<div className="stores">
<Stores />
</div>
</div>
</Col>
<Col xs={10}>
<Winks products={this.state.winks} />
</Col>
</Row>
</div>
</Grid>
)
答案 0 :(得分:1)
通常,您永远不必使用forceUpdate()
。相反,您应该使用this.setState()
来更新数据,因为它会使您的组件使用新数据自动重新渲染。
从您的示例中不清楚,但假设response
方法中的getWinks()
参数包含更新的产品,则应使用它来更新状态。
但是,由于您使用道具获取父级的初始产品,因此您需要将更新的产品传递回父级并让它运行this.setState({ products })
(这将触发重新渲染,从而导致您显示的用新数据重新渲染的组件。
答案 1 :(得分:0)
使用state
。比如说,使用状态loader
,当您调用true
时,它应设置为httpHandler
,并在异步操作完成时设置为false
。这样,更改状态将重新呈现组件而不包含任何forceupdate()
像这样。
getWinks (itemId) {
this.setState({loading: true})
this.httpHandler.post("/users/" + this.state.user.id + "/winks", {
user_id:this.state.user.id,
wink: {
product_id:itemId
}
}).then(function (response){
this.setState({loading: false})
}.bind(this))
}
答案 2 :(得分:0)
您的组件不会重新渲染,因为您没有更改其状态或道具,因此它没有任何更新,这只是反应的工作方式。
在您的代码中,您正在发送POST请求,但您没有对响应做任何事情。你能解释一下这个要求是做什么的吗?
答案 3 :(得分:0)
您的组件是props
和state
的功能。因此,无论何时更改,您的组件都会再次呈现。
如果传递给您组件的state
或props
从对该组件或任何父组件的调用setState(...)
变为,则您的组件将再次呈现。因此,唯一需要使用forceupdate()
的时间是当您需要将该组件呈现为其他功能的时候。
例如,假设您有一个Timer
组件正在传递属性elapsed
和runningSince
。 Timer
组件将根据elapsed
,runningSince
和Date.now()
计算显示给用户的时间。但是,除非用户单击“开始”或“停止”按钮,否则elapsed
和runningSince
不会更改。但是然后Timer
组件将不会显示实时计时器,因为没有任何东西可以触发它的render
函数。要解决此问题,您可以添加一个更新间隔,例如,每个forceupdate()
会调用50 ms
。