React context实战

916 阅读1分钟

src/context.js

import React from 'react';
export default  React.createContext({background:'red', color:'blue'});

src/app.js

import React, { Component } from 'react'
import Header from './header'
import Create from './create-task'
import Tasks from './tasks'
import Guess from './guess'
import Deleteall from './delete-all'
import Link from './link'
import Dialog from './Dialog'
import ThemeContext from './context'

import '../styles/App.css'

export default class App extends Component {
  state = {
    tasks: [],
    selectedTask: undefined,
    isShow:false
  }

  componentDidMount = () => {
    try {
        const json = localStorage.getItem('tasks')
        const tasks = JSON.parse(json)

        if (tasks) {
            this.setState(() => ({tasks}))
        }
    } catch(e) {
        this.setState(() => ({selectedTask: 'Something went wrong!'}))
    }
  }

  componentDidUpdate = (prevProps, prevState) => {
      if(prevState.tasks.length !== this.state.tasks.length) {
          const json = JSON.stringify(this.state.tasks)
          localStorage.setItem('tasks', json)
      }
  }

  deleteTask = (taskTodelete) => {
    this.setState((prevState) => ({
      tasks: prevState.tasks.filter((task) => taskTodelete !== task)
    }))
  }

  whatTodo = () => {
    this.setState({isShow:true});
    
  }

  deleteAll = () => {
    this.setState(() => ({tasks: []}))
  }

  closeModal = () => {
    this.setState(() => ({selectedTask: undefined}))
  }

  onSubmit = (event) => {
    event.preventDefault()
    const singletask = event.target.elements.singletask.value.trim().toLowerCase()
    if(!singletask) {
        this.setState(() => ({selectedTask: 'Please enter a task!'}))
    } else if(this.state.tasks.indexOf(singletask) > -1) {
        this.setState(() => ({selectedTask: 'This task already exists!'}))
    } else this.setState((prevState) => ({ tasks: [...prevState.tasks, singletask] }))
    event.target.elements.singletask.value = ''
  }
  render() {
    return (
      <ThemeContext.Provider value={{background:'green', color:'white'}}>
      <div>
        <Header />
        <Create 
        onSubmit={this.onSubmit} 
        />
        { this.state.tasks.length > 0 ?
          <Guess
            whatTodo={this.whatTodo}
          />
          : null
        }
        {
          this.state.tasks.length === 0 &&
          <div className="center-text">
            <h4>Please Enter a task!</h4>
          </div>
        }
        { this.state.tasks.length > 0 ?

          <Tasks
            tasks={this.state.tasks}
            deleteTask={this.deleteTask}
          />
          : null
        }
        { this.state.tasks.length > 0 ?
          <Deleteall
            deleteAll={this.deleteAll}
          />
          : null
        }

        <Dialog isShow={this.state.isShow}>
          <h1>测试一个dialog</h1>


        </Dialog>
        
        <Link />
      </div>
      </ThemeContext.Provider>
    )
  }
}

src/Top.js

import React from 'react'
import ThemeContext from './context';
class Top extends React.Component{
    constructor(props){
        super(props);
        this.state = {date: new Date()};
    }
    static contextType = ThemeContext;
    render(){
        const theme = this.context;
    return <h1>{theme.background}</h1>
    }
}
export default Top;

src/Dialog.jsx


import React from 'react';
import ReactDom from 'react-dom';
import ThemeContext from './context';
const styleObj = {
    position: 'absolute',
    width: '200px',
    height: '200px',
    marginTop: '-100px',
    marginLeft: '-100px',
    top: '50%',
    left: '50%',
    backgroundColor: 'blue'

}
const Dialog = (props) => {
    const obj = props.isShow ? { display: 'block' } : { display: 'none' };
    return <ThemeContext.Consumer>{(context)=>{
        return ReactDom.createPortal(
        
           <div style={Object.assign({}, styleObj, obj)}><p>{context.background}</p> {props.children}</div >
           
        
    , document.body)}}</ThemeContext.Consumer>
}

export default Dialog;