React 根 State 向下传递
此为完整Demo 可直接运行
Root
import React from 'react'
import {v4} from 'uuid'
import {ColorList} from "./color"
import {AddColorForm} from "./addColorForm"
export class App extends React.Component {
constructor(props) {
super(props);
this.state = {
colors: []
}
this.addColor = this.addColor.bind(this);
this.rateColor = this.rateColor.bind(this);
this.removeColor = this.removeColor.bind(this);
}
addColor(title, color) {
const colors = [
...this.state.colors,
{
id: v4(),
title,
color,
rating: 0
}
]
this.setState({colors});
}
rateColor(id, rating) {
const colors = this.state.colors.map(color =>
(color.id !== id) ?
color :
{
...color,
rating
}
)
this.setState({colors});
}
removeColor(id) {
const colors = this.state.colors.filter(
color => color.id !== id
)
this.setState({colors});
}
render() {
const {colors} = this.state;
return (
<div className="app">
<AddColorForm onNewColor={this.addColor}/>
<ColorList colors={colors}
onRate={this.rateColor}
onRemove={this.removeColor}/>
</div>
)
}
}
export default App
color
import React from 'react'
import {StarRating} from "./star";
const Color = ({title, color, rating = 0, onRemove = f => f, onRate = f => f}) => {
return (
<section className="color">
<h1>{title}</h1>
<button onClick={onRemove}>X</button>
<div className="color"
style={{backgroundColor: color}}>
</div>
<div>
<StarRating starsSelected={rating} onRate={onRate}/>
</div>
</section>
)
}
const ColorList = ({colors = [], onRate = f => f, onRemove = f => f}) => {
return (
<div className="color-list">
{(colors.length === 0) ?
<p>No Colors Listed. (Add a Color)</p> :
colors.map(color =>
<Color key={color.id}
{...color}
onRate={rating => onRate(color.id, rating)}
onRemove={() => onRemove(color.id)}
/>
)
}
</div>
)
}
export {Color, ColorList}
star
import React from 'react'
import './style.css'
const Star = ({selected = false, onClick = f => f}) => {
return (
<div className={(selected) ? "star selected" : "star"}
onClick={onClick}
>
</div>
)
}
const StarRating = ({starsSelected = 0, totalStars = 5, onRate = f => f}) => {
return (
<div className="star-rating">
{[...Array(totalStars)].map((n, i) =>
<Star key={i}
selected={i < starsSelected}
onClick={()=>onRate(i + 1)}
/>
)}
</div>
)
}
export {Star, StarRating}
color form
import React from 'react'
const AddColorForm = ({onNewColor = f => f}) => {
let _title, _color;
const submit = e => {
e.preventDefault();
alert(`New Color: ${_title.value} ${_color.value}`);
onNewColor(_title.value, _color.value);
_title.value = '';
_color.value = '#000000';
_title.focus();
}
return (
<form onSubmit={submit}>
<input ref={input => _title = input}
type="text"
placeholder="color title..."
required/>
<input ref= {input => _color = input}
type="color"
required/>
<button>ADD</button>
</form>
)
}
export {AddColorForm}
style
.star {
cursor: pointer;
height: 25px;
width: 25px;
margin: 2px;
float: left;
background-color: grey;
clip-path: polygon(
50% 0%,
63% 38%,
100% 38%,
69% 59%,
82% 100%,
50% 75%,
18% 100%,
31% 59%,
0% 38%,
37% 38%
);
}
.star.selected {
background-color: red;
}