javascript - Creating a button that fills in React - Stack Overflow

I'm new here and I have a question that I couldn't find answer to.. I am currently working on

I'm new here and I have a question that I couldn't find answer to..

I am currently working on a website using ReactJS, and I want to have a button that fills itself whenever the user clicks on it. The button should have a total of 5 stages to it.

I am not asking for you to code it for me, but simply help me finding the best approach to this thing.

So what exactly am I asking? As you can see in this

It's a boxed element that whenever the user clicks on it (it can click on the whole element), the progress fills and it bees something like this

So the first line is now marked. When the user presses on it again, the 2nd bar fills

Important - there will be text inside these bars that fills.

What have I done so far? I have been thinking of having 5 different images for every time the user presses on the element, but I was wondering if there might be a better approach to it (Like having the DIV background the image, and have sub-divs that fills up whenever the user presses... )

I hope I made myself clear, and thank you all for your time!

I'm new here and I have a question that I couldn't find answer to..

I am currently working on a website using ReactJS, and I want to have a button that fills itself whenever the user clicks on it. The button should have a total of 5 stages to it.

I am not asking for you to code it for me, but simply help me finding the best approach to this thing.

So what exactly am I asking? As you can see in this

It's a boxed element that whenever the user clicks on it (it can click on the whole element), the progress fills and it bees something like this

So the first line is now marked. When the user presses on it again, the 2nd bar fills

Important - there will be text inside these bars that fills.

What have I done so far? I have been thinking of having 5 different images for every time the user presses on the element, but I was wondering if there might be a better approach to it (Like having the DIV background the image, and have sub-divs that fills up whenever the user presses... )

I hope I made myself clear, and thank you all for your time!

Share Improve this question edited Oct 16, 2019 at 5:15 Jee Mok 6,5968 gold badges54 silver badges83 bronze badges asked Oct 16, 2019 at 4:29 LinirLinir 3881 gold badge3 silver badges14 bronze badges 3
  • Seems you can manage it through state. Doesn't it? – A. Nadjar Commented Oct 16, 2019 at 4:44
  • Thanks for the fast reply! So your'e saying its best to have 5 images and have them change based on the state ? If so, it is similar to what I was thinking. Thank you! – Linir Commented Oct 16, 2019 at 4:47
  • Thanks, Either image or CSS style.... both possible. – A. Nadjar Commented Oct 16, 2019 at 4:53
Add a ment  | 

5 Answers 5

Reset to default 1

Here is a working example. You don't need an image for all of the different states. It is far more flexible to do this dynamically with HTML.

The key to this is keeping track of the number of times the button has been clicked. In this example it uses currentState to keep track of how many times it has been clicked.

const defaultStyle = {
  width: 100,
  padding: 5,
};

class MultiLevelButton extends React.Component {
  constructor(props) {
    super(props);
    
    this.state = {
      currentState: 0,
    };
    
    this.handleClick = this.handleClick.bind(this);
  }
  
  handleClick() {
    const { currentState } = this.state;
    
    if (currentState < this.props.states.length) {
      this.setState({
        currentState: currentState + 1,
      });
    }
  }
  
  reset() {
    this.setState({
      currentState: 0,
    });
  }
  
  render() {
    const { currentState } = this.state;
    const { states } = this.props;
    
    return (
      <button onClick={this.handleClick} style={{border: 'none', outline: 'none'}}>
        {
          states
            .map((s, i) => {
              const stateNumber = states.length - i;
              const overrides = stateNumber <= currentState ? { backgroundColor: '#000', color: '#fff' } : {};
              const style = {
                ...defaultStyle,
                backgroundColor: s,
                ...overrides,
              };
              return <div style={{...style}}>{stateNumber}</div>
            })
        }
      </button>
    )
  }
}

const buttonRef = React.createRef();

ReactDOM.render(
  <div>
    <MultiLevelButton ref={buttonRef} states={['#bbb', '#ccc', '#ddd', '#eee', '#fff']} />
    <MultiLevelButton states={['#fcc', '#cfc', '#ccf']} />
    <div>
      <button onClick={() => buttonRef.current.reset()}>Reset</button>
    </div>
  </div>,
  document.getElementById('app')
);
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="app" />

As you are using react. use create step/level as ponent and you will pass props of styles. you can map that ponent 5 times or n times depending upon requirement. The view you have shown no need images use css to achieve it.

change props of ponent when user click on it.

You can use state in order to keep the click count and change the button background on the basis of click count.

const colors = ["#dfddc7", "#f58b54", "#a34a28", "#211717"]; //color array
class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      index : 0
    }
  }
  handleChange() { // function will be called whenever we click on button
   let {index} = this.state;
   if (index >= 5) {
    return; // you don't want to change color after count 5
   }
   index++;
   console.log(index);
   this.setState({index})
  }
  render() {
   const {index} = this.state;
   return (
    <div className="App">
     <button style = {{background:colors[index]}} //we are setting dynamic color from array on the basis of index
       onClick = {this.handleChange.bind(this)}> click to change images 
     </button>
     </div>
   );
  }
}

You can place <div></div> inside a button with different background color instead of images.

In the following example, I hold the number of clicks in the state. By paring this value with the index of the step, you can see if it needs to be green or transparent

const numberOfSteps = 5;
class App extends React.Component {
  state = {
    numberOfClicks: 0
  };

  handleClick = e => {
    this.setState({
      numberOfClicks: (this.state.numberOfClicks + 1) % (numberOfSteps + 1)
    }); // Use module (%) to reset the counter after 5 clicks
  };

  render() {
    const { numberOfClicks } = this.state;
    const steps = Array(numberOfSteps)
      .fill()
      .map((v, i) => i)
      .map((i, index) => {
        const color = numberOfClicks >= index + 1 ? "limegreen" : "transparent";
        return (
          <div
            style={{
              backgroundColor: color,
              height: "30px",
              border: ".5px solid gray"
            }}
          >
            Bar {index + 1}
          </div>
        );
      });
    return (
      <button
        className="button"
        style={{ height: "200px", width: "200px", backgroundColor: "lightgreen" }}
        onClick={this.handleClick}
      >
        {steps}
      </button>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root">
  <!-- This element's contents will be replaced with your ponent. -->
</div>

The key concept is state. When you click your button you should set some state, and when you render the button you should render it based on the state.

Here's a simple example where I render a button which contains 5 div elements that are filled (by setting backgroundColor style property) based on the state.

class Example extends Component {

    constructor(props) {
        super(props);

        this.state = {
            buttonState: 0,
        };
    }

    onClick = () => {
        let buttonState = this.state.buttonState;
        buttonState++;
        if(buttonState > 4) buttonState = 0; // wrap around from 4 - 0
        this.setState({buttonState: buttonState});
    }

    // render a button element with some text, and a background color based on whether filled is true/false
    renderButtonElement(elementText, filled) {
        const backgroundStyle = filled ? {backgroundColor: 'green'} : {backgroundColor: 'white'};
        const textStyle = {color: 'grey'};

        return(
            <div style={[backgroundStyle, textStyle]}>
                <div>{elementText}</div>
            </div>
        );
    }

    render() {
        return(
            <button
                onClick={this.onClick}
            >
                {/*  make a temporary array of 5 elements, map over them and render an element for each one */}
                {Array(5).fill().map((_, i) => this.renderButtonElement(i + 1, i <= this.state.buttonState))}
            </button>
        );
    }
}

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745169026a4614808.html

相关推荐

  • javascript - Creating a button that fills in React - Stack Overflow

    I'm new here and I have a question that I couldn't find answer to.. I am currently working on

    7小时前
    40

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信