Javascript 如何分离可重用组件内部的状态
编辑:我已尝试为每个实现使用this.props.id对每个组件实现的状态进行个性化设置。因此,我的目标是确保每次单击都会单独影响每个实现,而不是所有实现,但这种方法似乎失败了 我有一个可重复使用的滑块组件 在react组件中,我使用了几个幻灯片的util 我希望当我点击其中一个滑块时,这些滑块中只有一个会移动,但它们都会向左或向右移动 目前,当我点击其中一个组件的左/右按钮时,所有这些组件都会移动,那么如何使其成为我点击移动的唯一组件 这里是沙箱 如何区分我的可重用组件的状态 以下是我如何导入我的状态:Javascript 如何分离可重用组件内部的状态,javascript,reactjs,Javascript,Reactjs,编辑:我已尝试为每个实现使用this.props.id对每个组件实现的状态进行个性化设置。因此,我的目标是确保每次单击都会单独影响每个实现,而不是所有实现,但这种方法似乎失败了 我有一个可重复使用的滑块组件 在react组件中,我使用了几个幻灯片的util 我希望当我点击其中一个滑块时,这些滑块中只有一个会移动,但它们都会向左或向右移动 目前,当我点击其中一个组件的左/右按钮时,所有这些组件都会移动,那么如何使其成为我点击移动的唯一组件 这里是沙箱 如何区分我的可重用组件的状态 以下是我如何导入
import FruitSlideUtil from "~/lib/pizza/FoodSlideUtil/FoodSlideUtil"
import BeverageSlideUtil from "~/lib/pizza/FoodSlideUtil/FoodSlideUtil"
import DessertSlideUtil from "~/lib/pizza/FoodSlideUtil/FoodSlideUtil"
以下是我通常如何在父组件中实现它:
<div
className={style.slide_container}
ref="slideContainer"
>
<div
className={style.option_item_container}
>
<FruitSlideUtil
ref="FoodSlideUtil"
state={fruitSlideState}
scopeProps={this.state.scopeProps}
itemSelected={fruitStock}
optFood={null}
/>
</div>
</div>
state={
// scopeProps: this.props.scopeProps,
["scopeProps"+this.props.id]: 5,
// number of items in he slider
["totalSliderItem" +this.props.id]:0,
["distance"+ this.props.id]:0, // distance between two elements in px
["currentPosition"+this.props.id]:0, // current position
["updatedTotal" + this.props.id]:0, // total number of elements after adding remaining elements,
// element remaining outside foodScopeView
["remainOutsideLeft" +this.props.id]:0,
["remainOutsideRight"+this.props.id]:0
}
这里是处理可重用组件中的移动的函数:
componentDidMount(){
// set CSS variable
// § call body variable
let root= document.body;
// § update css variable CSS variable --unit-width
// call metacontainer ref
let SliderMetaContainer= this.refs.sliderMetaContainer
// get metacontainer width
let metaContainerWidth=SliderMetaContainer.getBoundingClientRect().width
let unitWidth= metaContainerWidth/this.state["scopeProps" +this.props.id]
root.style.setProperty('--unit-width', unitWidth + "px") ;
// set number of items contained in slider
let sliderContainer= this.refs.sliderContainer
let sliderContainerLength= sliderContainer.childElementCount
let updatedTotal=sliderContainerLength;
console.log("updatedTotal, this.state.scopeProps: ", updatedTotal, this.state["scopeProps" +this.props.id])
console.log("initialOutsideRight: ", initialOutsideRight)
console.log("distance: ", distance)
let initialOutsideRight= updatedTotal - this.state["scopeProps" +this.props.id]
// get the bounding rectangles
var div1rect = sliderContainer.children[0].getBoundingClientRect();
var div2rect = sliderContainer.children[1].getBoundingClientRect();
// get div1's center point
var div1x = div1rect.left + div1rect.width/2;
var div1y = div1rect.top + div1rect.height/2;
// get div2's center point
var div2x = div2rect.left + div2rect.width/2;
var div2y = div2rect.top + div2rect.height/2;
// calculate the distance using the Pythagorean Theorem (a^2 + b^2 = c^2)
var distanceSquared = Math.pow(div1x - div2x, 2) + Math.pow(div1y - div2y, 2);
var distance = Math.sqrt(distanceSquared);
// initialize state after componentDidMount
this.setState({
["totalSliderItem" + this.props.id]:sliderContainerLength,
["remainOutsideRight" +this.props.id]: initialOutsideRight,
["distance" + this.props.id]:distance,
["updatedTotal" +this.props.id]:updatedTotal
});
}
// when user click a button to move => handleSlideMove()
handleSlideMove=(direction)=>{
let cP;
// go right
if(direction === 'right'){
console.log("go toward right")
cP = this.state["currentPosition" +this.props.id] + this.state["scopeProps" +this.props.id];
console.log("cP: ", cP)
if(cP == this.state["updatedTotal" + this.props.id]){
// this.state.currentPosition = 0 ;
this.setState( currentState => ({
["currentPosition" + this.props.id]:0,
["remainOutsideLeft" +this.props.id]:0,
["remainOutsideRight" +this.props.id]:currentState["updatedTotal" + this.props.id] - currentState["scopeProps"+this.props.id],
}), () => {
document.body.style.setProperty('--item-left-food', 0 + "px");
});
}else{
if(this.state["remainOutsideRight"+ this.props.id] < this.state["scopeProps" +this.props.id]){
cP=this.state["currentPosition" +this.props.id] + this.state["remainOutsideRight" + this.props.id]
this.setState( currentState =>({
["currentPosition" +this.props.id]:cP,
["remainOutsideLeft" +this.props.id]:currentState["remainOutsideLeft"+this.props.id] + currentState["remainOutsideRight"+this.props.id],
// all remain outside right will be used
["remainOutsideRight"+ this.props.id]:currentState["remainOutsideRight" +this.props.id]- currentState["remainOutsideRight"+this.props.id],
}), () => {
document.body.style.setProperty('--item-left-food', -cP*this.state["distance" +this.props.id] + "px");
});
}
else{
this.setState(currentState =>({
["currentPosition" +this.props.id]:cP,
["remainOutsideLeft"+this.props.id]:currentState["remainOutsideLeft"+this.props.id] + currentState["scopeProps"+this.props.id],
// all remain outside right will be used
["remainOutsideRight" + this.props.id]:currentState["remainOutsideRight"+this.props.id] - currentState["scopeProps"+this.props.id],
}), () => {
document.body.style.setProperty('--item-left-food', -cP*this.state["distance" + this.props.id] + "px");
});
}
}
}
// go left
else{
console.log("go toward left")
cP = this.state["currentPosition" +this.props.id] - this.state["scopeProps" + this.props.id];
console.log("this.state.currentPosition, this.state.scopeProps: ",this.state["currentPosition" +this.props.id], this.state["scopeProps" +this.props.id])
console.log("this.state.currentPosition - this.state.scopeProps: ", this.state["currentPosition" +this.props.id] - this.state["scopeProps" + this.props.id])
if(this.state["currentPosition" + this.props.id] == 0){
console.log("this.state.currentPosition == 0: ")
// this.state.currentPosition = this.state.updatedTotal - scopeProps;
this.setState(currentState =>({
["currentPosition" +this.props.id]:currentState["updatedTotal"+this.props.id] - currentState["scopeProps"+this.props.id],
["remainOutsideLeft"+this.props.id]:currentState["updatedTotal"+this.props.id] - currentState["scopeProps"+this.props.id],
["remainOutsideRight"+this.props.id]:0
}),
() => {
document.body.style.setProperty('--item-left-food', - this.state["currentPosition"+this.props.id]*this.state["distance"+this.props.id] + "px");
})
}else{
console.log("this.state.currentPosition differ than 0")
console.log(
"this.state.remainOutsideLeft, this.state.scopeProps: ",
this.state["remainOutsideLeft"+this.props.id], this.state["scopeProps"+this.props.id]
)
console.log("this.state.remainOutsideleft < this.state.scopeProps: ", this.state["remainOutsideleft"+this.props.id] < this.state["scopeProps"+ this.props.id])
if(this.state["remainOutsideLeft" + this.props.id] < this.state["scopeProps" +this.props.id]){
console.log("differ than 0 remain inferior than scope: ")
cP=this.state["currentPosition"+this.props.id] - this.state["remainOutsideLeft"+this.props.id]
this.setState(currentState =>({
["currentPosition"+this.props.id]:cP,
["remainOutsideLeft" +this.props.id]:currentState["remainOutsideLeft"+this.props.id] - currentState["remainOutsideLeft"+this.props.id],
["remainOutsideRight" +this.props.id]:currentState["remainOutsideRight"+this.props.id] + currentState["remainOutsideLeft"+this.props.id]
}), () => {
document.body.style.setProperty('--item-left-food', -cP*this.state["distance" +this.props.id] + "px");
});
}
else{
console.log("differ than 0 remain superior to scope: ")
this.setState(currentState =>({
["currentPosition"+this.props.id]:cP,
["remainOutsideLeft"+this.props.id]:currentState["remainOutsideLeft"+this.props.id] - currentState["scopeProps"+this.props.id],
["remainOutsideRight" +this.props.id]:currentState["remainOutsideRight" +this.props.id] + currentState["scopeProps"+this.props.id]
}), () => {
document.body.style.setProperty('--item-left-food', -cP*this.state["distance"+this.props.id] + "px");
});
}
// this.setState(currentState => ({currentPosition:cP}), () => {
// document.body.style.setProperty('--item-left', -cP*this.state.distance + "px")
}
}
}
所以这里有很多问题。代码极其冗长且难以理解,而且您没有充分利用React提供的功能。我从未见过旋转木马中使用毕达哥拉斯定理!。为了回答您的问题,这些控件影响所有滑块的原因是,您使用添加到右/左函数主体中的CSS属性来控制它们的位置:
document.body.style.setProperty('--item-left-food', -cP*this.state["distance" +this.props.id] + "px");
对于React,除非绝对必要,否则您希望避免手动操作DOM或使用REF,您应该使用滑块组件内返回的JSX根据其内部状态有条件地添加任何类或样式。您在父组件中声明了3个相同状态的实例,作为一个名为state的道具,该道具从未使用过,并且使用不同的名称导入滑块组件3次。您应该只导入一次,传递更改所需的道具,并在组件内部设置默认状态或道具
是一篇关于使用React构建滑块组件的文章。你能发布组件代码和更改幻灯片的函数吗?@RutherfordWonkington是的,同时这里有一个沙盒,如果它能帮助你的话:'我从未见过旋转木马中使用的毕达哥拉斯定理!'哈哈,是的,这是我在这个密码上的特殊举动:p。好的,谢谢