React - Uncaught TypeError: Cannot read property 'toLowerCase' of undefined

React - Uncaught TypeError: Cannot read property 'toLowerCase' of undefined

在输入框输入颜色名称后,提交表单时出现错误:

TypeError: 无法读取未定义的 属性 'toLowerCase' (匿名函数) C:/Users/HP/Documents/WDB/React/Practice/colors-app/src/NewPaletteForm.js:117

  114 |     //to check -> is 'palette name' unique
  115 |     ValidatorForm.addValidationRule("isPaletteNameUnique", value => {
  116 |         return palettes.every(
> 117 |             ({ paletteName }) => paletteName.toLowerCase() !== value.toLowerCase()
  118 | ^       );
  119 |     });
  120 | })

App.js :(基于Class的组件)

class App extends Component {
  constructor(props) {
    super(props);
    this.state = { palettes: seedColors };
    this.findPalette = this.findPalette.bind(this);
    this.savePalette = this.savePalette.bind(this);
  }
savePalette(newPalette) {
    this.setState({ palettes: [...this.state.palettes, newPalette] });
  }

  render() {
    return (
      <Switch>
        <Route
          exact
          path='/palette/new'
          render={(routeProps) =>
            <NewPaletteForm
              savePalette={this.savePalette}
              palettes={this.state.palettes}
              {...routeProps}
            />}
        />

NewPaletteForm.js :(功能组件并使用反应挂钩)

function NewPaletteForm(props) {
    const classes = useStyles();
    const [open, setOpen] = useState(false);
    const [currentColor, setCurrentColor] = useState('teal');
    const [colors, setColors] = useState([{ color: 'pink', name: 'pink' }]);
    const [fields, setFields] = useState({
        newColorName: '',
        newPaletteName: ''
    })

    useEffect(() => {
        ValidatorForm.addValidationRule('isColorNameUnique', (value) => { 
            return colors.every(
                ({ name }) => name.toLowerCase() !== value.toLowerCase()
            );
        });

        ValidatorForm.addValidationRule('isColorUnique', (value) => { 
            return colors.every(
                ({ color }) => color !== currentColor
            );
        });

        ValidatorForm.addValidationRule("isPaletteNameUnique", value => {
            return props.palettes.every(
                ({ paletteName }) => paletteName.toLowerCase() !== value.toLowerCase()
            );
        });
    })
  function addNewColor() {
    const newColor = {
        color: currentColor,
        name: fields.newColorName
    }
    setColors(oldColors => [...oldColors, newColor]);
    setFields({ newColorName: '' });
};

function handleChange(evt) {
    setFields({ ...fields, [evt.target.name]: evt.target.value });

}

function handleSubmit() {
    let newName = fields.newPaletteName;
    const newPalette = {
        paletteName: newName,
        id: newName.toLowerCase().replace(/ /g, '-'),
        colors: colors
    }
    props.savePalette(newPalette);
    props.history.push('/');
}

颜色和调色板的验证器表单组件:

<ValidatorForm onSubmit={handleSubmit}>
                        <TextValidator
                            label='Palette Name'
                            value={fields.newPaletteName}
                            name='newPaletteName'
                            onChange={handleChange}
                            validators={['required', 'isPaletteNameUnique']}
                            errorMessages={['Enter Palette Name', 'Name already used']} />
                        <Button variant='contained' color='primary' type='submit'>
                            Save Palette
                        </Button>
                    </ValidatorForm>

<ValidatorForm onSubmit={addNewColor}>
                    <TextValidator
                        value={fields.newColorName}
                        name='newColorName'
                        onChange={handleChange}
                        validators={['required', 'isColorNameUnique', 'isColorUnique']}
                        errorMessages={['Enter a color name', 'Color name must be unique', 'Color already used!']}
                    />
                    <Button
                        variant='contained'
                        type='submit'
                        color='primary'
                        style={{
                            backgroundColor: currentColor
                        }}
                    >
                        Add Color
                    </Button>
                </ValidatorForm>

seedColors.js:

export default [
    {
        paletteName: "Material UI Colors",
        id: "material-ui-colors",
        emoji: "",
        colors: [
            { name: "red", color: "#F44336" },
            { name: "pink", color: "#E91E63" },
            { name: "purple", color: "#9C27B0" },
            { name: "deeppurple", color: "#673AB7" },
            { name: "indigo", color: "#3F51B5" },
            { name: "blue", color: "#2196F3" },
            { name: "lightblue", color: "#03A9F4" },
            { name: "cyan", color: "#00BCD4" },
            { name: "teal", color: "#009688" },
            { name: "green", color: "#4CAF50" },
            { name: "lightgreen", color: "#8BC34A" },
            { name: "lime", color: "#CDDC39" },
            { name: "yellow", color: "#FFEB3B" },
            { name: "amber", color: "#FFC107" },
            { name: "orange", color: "#FF9800" },
            { name: "deeporange", color: "#FF5722" },
            { name: "brown", color: "#795548" },
            { name: "grey", color: "#9E9E9E" },
            { name: "bluegrey", color: "#607D8B" }
        ]
    },
    {
        paletteName: "Flat UI Colors v1",
        id: "flat-ui-colors-v1",
        emoji: "",
        colors: [
            { name: "Turquoise", color: "#1abc9c" },
            { name: "Emerald", color: "#2ecc71" },
            { name: "PeterRiver", color: "#3498db" },
            { name: "Amethyst", color: "#9b59b6" },
            { name: "WetAsphalt", color: "#34495e" },
            { name: "GreenSea", color: "#16a085" },
            { name: "Nephritis", color: "#27ae60" },
            { name: "BelizeHole", color: "#2980b9" },
            { name: "Wisteria", color: "#8e44ad" },
            { name: "MidnightBlue", color: "#2c3e50" },
            { name: "SunFlower", color: "#f1c40f" },
            { name: "Carrot", color: "#e67e22" },
            { name: "Alizarin", color: "#e74c3c" },
            { name: "Clouds", color: "#ecf0f1" },
            { name: "Concrete", color: "#95a5a6" },
            { name: "Orange", color: "#f39c12" },
            { name: "Pumpkin", color: "#d35400" },
            { name: "Pomegranate", color: "#c0392b" },
            { name: "Silver", color: "#bdc3c7" },
            { name: "Asbestos", color: "#7f8c8d" }
        ]
    }
]

您可以做的是在调用 toLowerCase 之前检查 value 是否存在。 尝试使用 ?.,像这样

而不是使用 value.toLowerCase() 使用 value?.toLowerCase().

如果 value 未定义或为 null,则不会调用 toLowerCase()

如果 paletteName 失败了,您可以使用 paletteName?.toLowerCase()

如果你想完全安全,你可以

paletteName?.toLowerCase() !== value?.toLowerCase()