反应 - 未捕获的类型错误:无法读取未定义的属性“toLowerCase”

Posted

技术标签:

【中文标题】反应 - 未捕获的类型错误:无法读取未定义的属性“toLowerCase”【英文标题】:React - Uncaught TypeError: Cannot read property 'toLowerCase' of undefined 【发布时间】:2021-10-13 17:42:50 【问题描述】:

在输入字段中输入颜色名称后,当我提交表单时,出现错误:

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 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" 
        ]
    
]

【问题讨论】:

paletteName.toLowerCase() !== value.toLowerCase() 中的哪一个是未定义的?您已经尝试过什么调试?似乎paletteName 不是palettes 属性中元素的属性,或者value 未定义。由于value 似乎在上面的其他验证中定义,因此palettes 似乎不是您期望的值。你能分享seedColors是什么吗?我怀疑您在初始渲染时看到了这个问题,还是接近它? 检查一次seedColors,它有paletteName ? 我已经添加了 seedColors.js 文件 添加日志,查看paletteNamevalue的值是多少 【参考方案1】:

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

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

这样如果value 未定义或为空,它就不会调用toLowerCase()

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

如果你想完全安全,你就去做

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

【讨论】:

以上是关于反应 - 未捕获的类型错误:无法读取未定义的属性“toLowerCase”的主要内容,如果未能解决你的问题,请参考以下文章

与 ES7 反应:未捕获的类型错误:无法读取未定义的属性“状态”[重复]

未捕获的类型错误:在开关函数开始时无法读取未定义的属性“类型”

错误:未捕获 [TypeError:无法读取未定义 Jest 反应测试的属性“x”

反应路由器:无法读取未定义的属性“路径名”

未捕获的类型错误:无法读取未定义的属性“区域”?

错误:`未捕获(承诺中)类型错误:无法读取未定义的属性'doc'`