更改在 React 中多次声明的一个组件的状态 - 更好的做法?

Changing the state of one component that gets declared multiple times in React - Better Practices?

首先,这段代码对我有用,但我想知道是否有任何问题。

我尝试改变一个被多次调用的组件的状态,这比我在 React 中意识到的要困难得多。我能够完成它,但我觉得我在 toggleClass 中做了一些不好的练习。如果这是一个很好的做法,但有更好的方法来做到这一点,或者如果没有任何问题,这个菜鸟很想知道。

ButtonContainer.js

import React from 'react'
import Button from './Button'

export default class ButtonContainer extends React.Component {
    state = {
        colors: ['red', 'blue', 'green'],
        active: true
    }
    toggleClass = (color, id) => {
        let colors = [...this.state.colors]
        colors.map((newColor, index) => {
            if (id === index) {
                let copy = { ...colors[index] }
                if (color === 'not') {
                    if (index === 0) {
                        copy = 'red'
                    } else if (index === 1) {
                        copy = 'blue'
                    } else if (index === 2) {
                        copy = 'green'
                    }
                } else {
                    copy = 'not'
                }
                colors[index] = copy
                this.setState({ colors })
            }
        })
    }
    render() {
        return (
            <div className='button-container'>
                {this.state.colors.map((color, index) =>
                    <Button
                        toggleClass={this.toggleClass}
                        key={index}
                        id={index}
                        name={color}
                    />
                )}
            </div>
        )
    }
}

Button.js

import React from 'react'

const Button = (props) => (
    <button
        className={`button-component ${props.name}`}
        onClick={() => props.toggleClass(props.name, props.id)}
    >
        {props.name}
    </button>
)

export default Button

CSS

.button-container {
    margin: 10rem auto;
    text-align: center;
}
.button-component {
    padding: 4rem;
    margin: 0 2rem;
}

.red {
    background: red;
}

.blue {
    background: blue;
}

.green {
    background: green;
}

.not {
    background: none;
}

-- 更新 --

改进的 toggleClass

toggleClass = (color, id) => {
        let colors = [...this.state.colors]
        const newColors = colors.map((newColor, index) => {
            if (id === index) {
                const copyMap = { 0: 'red', 1: 'blue', 2: 'green' }
                const copy = color === 'not' ? copyMap[index] : 'not'
                return copy
            } else {
                return newColor
            }
        })
        this.setState({ colors: newColors })
    }

你寻求建议是件好事 - 尽早学习如何以正确的方式做事会带来回报。

  • Array.map的目的是在已有数组的基础上创建一个新数组。最佳做法是避免在那里做额外的事情,比如 setState。但是你应该在任何情况下都不要在迭代数组时改变数组的内容(colors[index] = copy)
  • 有几个未使用的变量浮动,this.state.activenewColor。清理它,代码将更易于阅读。
  • 大多数情况下,您应该避免使用 let 声明,而是使用 const。随着时间的推移,您会发​​现转换变量的代码比创建具有描述性名称的新变量的代码更难推理。
  • 一种可能有助于清理那些长 if 语句的模式是构建引用对象(或数组)。
const copyMap = { 0: 'red', 1: 'blue', 'green' }
const copy = color === 'not' ? copyMap[index] : 'not'

可以替换所有这些代码:

                if (color === 'not') {
                    if (index === 0) {
                        copy = 'red'
                    } else if (index === 1) {
                        copy = 'blue'
                    } else if (index === 2) {
                        copy = 'green'
                    }
                } else {
                    copy = 'not'
                }