Javascript 如何分离可重用组件内部的状态

Javascript 如何分离可重用组件内部的状态,javascript,reactjs,Javascript,Reactjs,编辑:我已尝试为每个实现使用this.props.id对每个组件实现的状态进行个性化设置。因此,我的目标是确保每次单击都会单独影响每个实现,而不是所有实现,但这种方法似乎失败了 我有一个可重复使用的滑块组件 在react组件中,我使用了几个幻灯片的util 我希望当我点击其中一个滑块时,这些滑块中只有一个会移动,但它们都会向左或向右移动 目前,当我点击其中一个组件的左/右按钮时,所有这些组件都会移动,那么如何使其成为我点击移动的唯一组件 这里是沙箱 如何区分我的可重用组件的状态 以下是我如何导入

编辑:我已尝试为每个实现使用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。好的,谢谢