React State

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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值