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()
在输入框输入颜色名称后,提交表单时出现错误:
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()