我的 'NewPaletteForm' 是一个功能组件,因为我使用了react hooks。
因此,当我单击“保存调色板”按钮时,会出现一个错误,提示“ props.savePalette 不是函数”。
错误:- TypeError:props.savePalette 不是函数
代码:
'应用程序.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);
}
findPalette(id) {
return this.state.palettes.find(function (palette) {
return palette.id === id;
});
}
savePalette(newPalette) {
this.setState({ palettes: [...this.state.palettes, newPalette] });
}
render() {
return (
<Switch>
<Route
exact
path='/palette/new'
render={(routeProps) => <NewPaletteForm savePalette={this.savePalette} {...routeProps} />} />
'NewPaletteForm.js' :包含反应钩子的功能组件
function NewPaletteForm() {
const classes = useStyles();
const [open, setOpen] = useState(false);
const [currentColor, setCurrentColor] = useState('teal');
const [colors, setColors] = useState([{ color: 'pink', name: 'pink' }]);
const [newName, setNewName] = useState('');
useEffect(() => {
ValidatorForm.addValidationRule('isColorNameUnique', (value) => {
return colors.every(
({ name }) => name.toLowerCase() !== value.toLowerCase()
);
});
ValidatorForm.addValidationRule('isColorUnique', (value) => {
return colors.every(
({ color }) => color !== currentColor
);
});
})
const handleDrawerOpen = () => {
setOpen(true);
};
const handleDrawerClose = () => {
setOpen(false);
};
function updateCurrentColor(newColor) {
setCurrentColor(newColor.hex);
};
function addNewColor() {
const newColor = {
color: currentColor,
name: newName
}
setColors(oldColors => [...oldColors, newColor]);
setNewName('');
};
function handleChange(evt) {
setNewName(evt.target.value);
}
function handleSubmit(props) {
const newPalette = {
paletteName: 'Test Palette',
colors: colors
}
props.savePalette(newPalette);
props.history.push('/');
}
return (
<div className={classes.root}>
<CssBaseline />
<AppBar
position="fixed"
color='default'
className={clsx(classes.appBar, {
[classes.appBarShift]: open,
})}
>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
onClick={handleDrawerOpen}
edge="start"
className={clsx(classes.menuButton, open && classes.hide)}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" noWrap>
Persistent drawer
</Typography>
<Button variant='contained' color='primary' onClick={handleSubmit}>Save Palette</Button>
</Toolbar>
</AppBar>
<Drawer
className={classes.drawer}
variant="persistent"
anchor="left"
open={open}
classes={{
paper: classes.drawerPaper,
}}
>
<div className={classes.drawerHeader}>
<IconButton onClick={handleDrawerClose}>
<ChevronLeftIcon />
</IconButton>
</div>
<Typography variant='h4'>Design Your Palette</Typography>
<div>
<Button variant="contained" color="secondary">
Clear Palette
</Button>
<Button variant="contained" color="primary">
Random Color
</Button>
</div>
<Divider />
<ChromePicker color={currentColor} onChangeComplete={updateCurrentColor} />
<ValidatorForm onSubmit={addNewColor}>
<TextValidator
value={newName}
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>
</Drawer>
<main
className={clsx(classes.content, {
[classes.contentShift]: open,
})}
>
<div className={classes.drawerHeader} />
{colors.map(color => (
<DraggableColorBox color={color.color} name={color.name} />
))}
</main>
</div>
);
}
NewPaletteForm 组件中的按钮:(使用的 Material UI 按钮组件)
<Button variant='contained' color='primary' onClick={handleSubmit}>Save Palette</Button>