简体   繁体   中英

How to make buttons act as radio buttons in React.js by changing states?

I am fairly new to React and wanted to try my hand at making a pathfinding visualizer. I want to have buttons that can be clicked which would make that particular pathfinding algorithm active while all else are inactive but I am unable to achieve this.

I have an Options component which renders the buttons:

export class Options extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            dijkstra: false,
            aStar: false,
            bestSearch: false,
            bfs: false,
            dfs: false,
        };

        this.handleClick = this.handleClick.bind(this);
    }

    handleClick(name) {
        this.setState({
            dijkstra: false,
            aStar: false,
            bestSearch: false,
            bfs: false,
            dfs: false,
        });

        this.setState({ [name]: true });
    }

    render() {
        return (
            <div className='toolbar'>
                <div className='algorithms'>
                    <Button
                        name="Dijkstra's Algorithm"
                        type='dijkstra'
                        isActive={this.state.dijkstra}
                        onClick={this.handleClick}
                    />
                    <Button
                        name='A* Algorithm'
                        type='aStar'
                        isActive={this.state.aStar}
                        onClick={this.handleClick}
                    />
                    <Button
                        name='Best First Search'
                        type='bestSearch'
                        isActive={this.state.bestSearch}
                        onClick={this.handleClick}
                    />
                    <Button
                        name='BFS'
                        type='bfs'
                        isActive={this.state.bfs}
                        onClick={this.handleClick}
                    />
                    <Button
                        name='DFS'
                        type='dfs'
                        isActive={this.state.dfs}
                        onClick={this.handleClick}
                    />
                </div>
                <div className='info'></div>
                <div className='legend'></div>
            </div>
        );
    }
}

the state is used to keep track of which algorithm is active while handleClick changes the state based on the key of the button. The following is the code for the Button component:

export class Button extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            isActive: false,
        };
    }

    componentWillReceiveProps() {
        if (this.props.isActive) this.setState({ isActive: true });
    }

    render() {
        let active = "";
        if (this.state.isActive) {
            active = "active";
        }
        return (
            <button
                className={`button ${active}`}
                onClick={this.props.onClick(this.props.type)}
            >
                {this.props.name}
            </button>
        );
    }
}

I receive an error "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops."

Any help with how I can rectify this or a better way to implement this?

When you do this:

<button
    className={`button ${active}`}
    onClick={this.props.onClick(this.props.type)}
>

it is going to set onClick to whatever this.props.onClick(this.props.type) returns. So every time it renders, it is going to call this.props.onClick , which is going to call setState , which is going to cause a rerender, which will call it again, etc.

You probably want to do:

onClick={() => this.props.onClick(this.props.type)}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM