React 学习笔记

文章目录

  • React 学习笔记
    • 安装
  • 基础概念
    • 变量 css
    • 列表
    • 组件
    • 事件处理
    • 事件对象
    • state
    • 表单处理
    • 一个实现评论的案例
  • 高阶概念
    • props
      • 传递数据
      • 函数传递数据
      • constructor
      • props children
      • props校验
      • props校验
    • 组件通信
      • 父传子
      • 子传父
      • 兄弟组件通讯
      • Context
  • 各种细节
    • setState() 异步更新数据
    • setState() 二次调用
    • setState() 同步
    • JSX 语法的转化过程
    • 组件更新机制
    • 组件性能优化
    • 虚拟DOM 和 Diff算法
  • v6 路由

React 学习笔记

  • 学习课程来自黑马程序员

安装

  • node.js 环境
  • 安装create-react-app
npm isntall -g create-react-app
  • yarn 安装
npm install -g yarn
  • 创建项目
create-react-app  my-app
  • 开始项目
npm start
yarn start
  • 遇到的报错

Cannot find module ‘react-dev-utils/getPublicUrlOrPath’

npm update
npm install --save-dev react-dev-utils
  • chrome 插件

React 学习笔记_第1张图片

基础概念

变量 css

const name = "xiaoxiaoran"
const age = 11
//const title = (

JSX,name={name},age={age}

)
const title = (<h1 className="title" >JSX,name={name},age={age}<span /></h1>) ReactDom.render(title, document.getElementById('root'))

列表

const songs = [{ id: 1, name: 'song1' }, { id: 2, name: 'song2' }, { id: 3, name: 'song3' }]
const list = (<ul>{songs.map(item => <li key={item.id}> {item.name}</li>)}</ul>)
ReactDom.render(list, document.getElementById('root'))

组件

  • 抽离到外部的/组件
import React from "react";
class Hello extends React.Component {
    render() {
        return 
抽离到js文件中的类组件
} } export default Hello
import Hello from './js/Hello.js'

//const Hello = () => 
函数组件
//function Hello() { return (
函数组件
) }
//class Hello extends React.Component { render() { return
类组件
} }
ReactDom.render(<Hello />, document.getElementById('root'))

事件处理

// class App extends React.Component {
//     handleClick() { alert('xiuxiu') }
//     render() {
//         return ()
//     }

// }

function App() {
    function handleClick() { alert('xiuxiu') }
    return (<button onClick={handleClick}>click</button>)
}

ReactDom.render(<App />, document.getElementById('root'))

事件对象

class App1 extends React.Component {
    handleClick(e) {
        e.preventDefault()
        alert('阻止默认行为')
    }
    render() {
        return (<a href="https://xiaoxiaoran.top" onClick={this.handleClick}>click</a>)
    }
}

ReactDom.render(<App1 />, document.getElementById('root'))

state

class App2 extends React.Component {
    state = { count: 0 }
    f1() { this.setState({ count: this.state.count + 1 }) }

    constructor() {
        super()
        this.state = { count: 100 }
        // bind this指向实例
        this.f1 = this.f1.bind(this)
    }

    render() {
        return (
            <div>
                <h1>count={this.state.count}</h1>

                {/*  */}

                {/*  */}

                <button onClick={this.f1} >+1</button>

            </div>
        )
    }
}
ReactDom.render(<App2 />, document.getElementById('root'))

表单处理

class App3 extends React.Component {
    state = {
        txt: '',
        content: '',
        isCheck: true
    }
    handleChange = e => {
        const target = e.target
        const value = target.type === 'checkbox' ? target.checked : target.value
        const name = target.name
        this.setState({
            [name]: value
        })
    }

    render() {
        return (
            <div>
                <input name="txt" type="text" value={this.state.txt} onChange={this.handleChange} /><br />
                <textarea name="content" value={this.state.content} onChange={this.handleChange} />
                <input name="isCheck" type="checkbox" checked={this.state.isCheck} onChange={this.handleChange} />
            </div>
        )
    }
}

ReactDom.render(<App3 />, document.getElementById('root'))

一个实现评论的案例

React 学习笔记_第2张图片

  • index.css
.title {
  text-align: center;
}

.app {
  width: 300px;
  padding: 10px;
  border: 1px solid #999;
}

.user {
  width: 100%;
  box-sizing: border-box;
  margin-bottom: 10px;
}

.content {
  width: 100%;
  box-sizing: border-box;
  margin-bottom: 10px;
}

.no-comment {
  text-align: center;
  margin-top: 30px;
}
  • index.js
import React from 'react'
import ReactDOM from 'react-dom'


import './index.css'

class App extends React.Component {
    // 初始化状态
    state = {
        comments: [
            { id: 1, name: 'jack', content: '沙发!!!' },
            { id: 2, name: 'rose', content: '板凳~' },
            { id: 3, name: 'tom', content: '楼主好人' }
        ],

        // 评论人
        userName: '',
        // 评论内容:
        userContent: ''
    }

    // 渲染评论列表:
    renderList() {
        const { comments } = this.state

        if (comments.length === 0) { return <div className="no-comment">暂无评论,快去评论吧~</div> }

        return (
            <ul>
                {comments.map(item => (
                    <li key={item.id}>
                        <h3>评论人:{item.name}</h3>
                        <p>评论内容:{item.content}</p>
                    </li>
                ))}
            </ul>
        )
    }

    // 处理表单元素值
    handleForm = e => {
        const { name, value } = e.target

        this.setState({
            [name]: value
        })
    }

    // 发表评论:
    addComment = () => {
        const { comments, userName, userContent } = this.state

        // 非空校验
        if (userName.trim() === '' || userContent.trim() === '') {
            alert('请输入评论人和评论内容')
            return
        }

        // 将评论信息添加到state中
        const newComments = [
            {
                id: Math.random(),
                name: userName,
                content: userContent
            },
            ...comments
        ]

        // 文本框的值如何清空? 要清空文本框只需要将其对应的state清空即可
        this.setState({
            comments: newComments,
            userName: '',
            userContent: ''
        })
    }



    render() {
        const { userName, userContent } = this.state

        return (
            <div className="app">
                <div>
                    <input className="user" type="text" placeholder="请输入评论人" value={userName} name="userName" onChange={this.handleForm} />
                    <br />
                    <textarea className="content" cols="30" rows="10" placeholder="请输入评论内容" value={userContent} name="userContent" onChange={this.handleForm} />
                    <br />
                    <button onClick={this.addComment}>发表评论</button>
                </div>

                {/* 通过条件渲染决定渲染什么内容: */}
                {this.renderList()}
            </div>
        )
    }
}

// 渲染组件 
ReactDOM.render(<App />, document.getElementById('root'))

高阶概念

props

传递数据

class Hello extends React.Component {
    render() {
        console.log(this.props)
        return (
            <div>
                <h1>props: {this.props.age} {this.props.name} </h1>
            </div>
        )
    }
}

// 1 传递数据
ReactDOM.render(<Hello name="rose" age={19} />, document.getElementById('root'))

函数传递数据

// 2 接收数据
const Hello = xiao => {
    // xiao是一个对象
    console.log(xiao)
    return (
        <div>
            <h1>props:{xiao.name} {xiao.age} </h1>
        </div>
    )
}

// 1 传递数据
ReactDOM.render(<Hello name="jack" age={19} />, document.getElementById('root')) 

constructor

class Hello extends React.Component {
    // 推荐使用props作为constructor的参数!!
    constructor(props) {
        super(props)
        // console.log(this.props)
        console.log(props)
    }

    render() {
        console.log('render:', this.props)

        return (
            <div>
                <h1>props:{this.props.name} {this.props.colors}</h1>
            </div>
        )
    }
}

ReactDOM.render(<Hello name="rose" age={19} colors={['red', 'green', 'blue']} fn={() => console.log('这是一个函数')} tag={<p>这是一个p标签</p>} />, document.getElementById('root'))

props children

import React from 'react'
import ReactDOM from 'react-dom'

const App = props => {
  console.log(props)
  return (
    <div>
      <h1>组件标签的子节点:</h1>
      {props.children}
    </div>
  )
}

ReactDOM.render(<App>我是子节点</App>, document.getElementById('root')) 

props校验

import React from 'react'
import ReactDOM from 'react-dom'

import PropTypes from 'prop-types'

const App = props => {
    const arr = props.colors
    const lis = arr.map((item, index) => <li key={index}>{item}</li>)

    return <ul>{lis}</ul>
}

// 添加props校验
App.propTypes = {
    colors: PropTypes.array
}

ReactDOM.render(
    <App colors={['red', 'blue']} />,
    document.getElementById('root')
)

props校验

import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'

const App = props => {
    return (
        <div>
            <h1>props校验:</h1>
        </div>
    )
}

// 添加props校验
// 属性 a 的类型:      数值(number)
// 属性 fn 的类型:     函数(func)并且为必填项
// 属性 tag 的类型:    React元素(element)
// 属性 filter 的类型: 对象({area: '上海', price: 1999})
App.propTypes = {
    a: PropTypes.number,
    fn: PropTypes.func.isRequired,
    tag: PropTypes.element,
    filter: PropTypes.shape({
        area: PropTypes.string,
        price: PropTypes.number
    })
}

ReactDOM.render(<App fn={() => { }} />, document.getElementById('root'))

组件通信

父传子

import React from 'react'
import ReactDOM from 'react-dom'


// 父组件
class Parent extends React.Component {
    state = { xiao: 1 }
    render() {
        return (
            <div className="parent">
                父组件:
                <Child name={this.state.xiao} />
            </div>
        )
    }
}

// 子组件
const Child = temp => {
    return (
        <div className="child">
            <p>子组件,接收到父组件的数据:{temp.name}</p>
        </div>
    )
}

ReactDOM.render(<Parent />, document.getElementById('root'))

子传父

import React from 'react'
import ReactDOM from 'react-dom'

// 父组件
class Parent extends React.Component {
    state = { parentMsg: '' }

    // 提供回调函数,用来接收数据
    getChildMsg = data => {
        console.log('接收到子组件中传递过来的数据:', data)
        this.setState({ parentMsg: data })
    }

    render() {
        return (
            <div className="parent">
                父组件:{this.state.parentMsg}
                <Child getMsg={this.getChildMsg} />
            </div>
        )
    }
}

// 子组件
class Child extends React.Component {
    state = {
        msg: '刷抖音'
    }

    handleClick = () => {
        // 子组件调用父组件中传递过来的回调函数
        this.props.getMsg(this.state.msg)
    }

    render() {
        return (
            <div className="child">
                子组件:{' '}
                <button onClick={this.handleClick}>点我,给父组件传递数据</button>
            </div>
        )
    }
}

ReactDOM.render(<Parent />, document.getElementById('root'))

兄弟组件通讯

import React from 'react'
import ReactDOM from 'react-dom'


// 父组件
class Counter extends React.Component {
    // 提供共享状态
    state = { count: 0 }
    // 提供修改状态的方法
    onIncrement = () => { this.setState({ count: this.state.count + 1 }) }
    render() {
        return (
            <div>
                <Child1 count={this.state.count} />
                <Child2 onIncrement={this.onIncrement} />
            </div>
        )
    }
}

const Child1 = temp => { return <h1>计数器:{temp.count}</h1> }

const Child2 = temp => { return <button onClick={() => temp.onIncrement()}>+1</button> }

ReactDOM.render(<Counter />, document.getElementById('root'))

Context

import React from 'react'
import ReactDOM from 'react-dom'

// 创建context得到两个组件
const { Provider, Consumer } = React.createContext()

class App extends React.Component {
    render() {
        return (
            <Provider value="xiaoxiaoran">
                <div className="app">
                    <Node />
                </div>
            </Provider>
        )
    }
}

const Node = props => {
    return (
        <div className="node">
            <SubNode />
        </div>
    )
}

const SubNode = props => {
    return (
        <div className="subnode">
            <Child />
        </div>
    )
}

const Child = props => {
    return (
        <div className="child">
            <Consumer>{data => <span>我是value={data}</span>}</Consumer>
        </div>
    )
}

ReactDOM.render(<App />, document.getElementById('root'))

各种细节

setState() 异步更新数据

import React from 'react'
import ReactDOM from 'react-dom'

class App extends React.Component {
  state = { count: 1 }
  handleClick = () => {
    // 此处,更新state
    // 注意:异步更新数据的!!!
    this.setState({ count: this.state.count + 1 })
    console.log('count:', this.state.count) // 1
    this.setState({ count: this.state.count + 1 })
    console.log('count:', this.state.count) // 1
  }

  render() {
    console.log('render')
    return (
      <div>
        <h1>计数器:{this.state.count}</h1>
        <button onClick={this.handleClick}>+1</button>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'))

setState() 二次调用

import React from 'react'
import ReactDOM from 'react-dom'

class App extends React.Component {
  state = { count: 1 }

  handleClick = () => {
    // 推荐语法:
    // 注意:这种语法也是异步更新state的!
    this.setState((state, props) => {
      return {
        count: state.count + 1 // 1 + 1
      }
    })
    this.setState((state, props) => {
      console.log('第二次调用:', state)
      return {
        count: state.count + 1
      }
    })
    console.log('count:', this.state.count) // 1
  }

  render() {
    return (
      <div>
        <h1>计数器:{this.state.count}</h1>
        <button onClick={this.handleClick}>+1</button>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'))

setState() 同步

import React from 'react'
import ReactDOM from 'react-dom'


class App extends React.Component {
  state = {
    count: 1
  }

  handleClick = () => {
    this.setState(
      (state, props) => {
        return {
          count: state.count + 1
        }
      },
      // 状态更新后并且重新渲染后,立即执行:
      () => {
        console.log('状态更新完成:', this.state.count) // 2
        console.log(document.getElementById('title').innerText)
        document.title = '更新后的count为:' + this.state.count
      }
    )
    console.log(this.state.count) // 1
  }

  render() {
    return (
      <div>
        <h1 id="title">计数器:{this.state.count}</h1>
        <button onClick={this.handleClick}>+1</button>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'))

JSX 语法的转化过程

import React from 'react'
import ReactDOM from 'react-dom'

// const element = 

Hello JSX!

const element = React.createElement( 'h1', { className: 'greeting' }, 'Hello JSX!' ) console.log(element) ReactDOM.render(element, document.getElementById('root'))

组件更新机制

  • index.css
.app {
    width: 800px;
    padding: 20px;
}

.app-wrapper {
    display: flex;
}

.parent {
    flex: 1;
    height: 300px;
    background-color: skyblue;
}

.parent:first-child {
    margin-right: 30px;
}

.parent-wrapper {
    display: flex;
}

.child {
    flex: 1;
    height: 200px;
    background-color: yellowgreen;
}

.child:first-child {
    margin-right: 20px;
}

  • index.js
import React from 'react'
import ReactDOM from 'react-dom'


import './index.css'

// 根组件  二叉树的先序遍历
class App extends React.Component {
  state = {
    color: '#369'
  }

  getColor() {
    return Math.floor(Math.random() * 256)
  }

  changeBG = () => {
    this.setState(() => {
      return {
        color: `rgb(${this.getColor()}, ${this.getColor()}, ${this.getColor()})`
      }
    })
  }

  render() {
    console.log('根组件')
    return (
      <div className="app" style={{ backgroundColor: this.state.color }}>
        <button onClick={this.changeBG}>根组件 - 切换颜色状态</button>
        <div className="app-wrapper">
          <Parent1 />
          <Parent2 />
        </div>
      </div>
    )
  }
}

// ------------------------左侧---------------------------

class Parent1 extends React.Component {
  state = {
    count: 0
  }

  handleClick = () => {
    this.setState(state => ({ count: state.count + 1 }))
  }
  render() {
    console.log('左侧父组件')
    return (
      <div className="parent">
        <h2>
          左侧 - 父组件1
          <button onClick={this.handleClick}>点我({this.state.count}</button>
        </h2>
        <div className="parent-wrapper">
          <Child1 />
          <Child2 />
        </div>
      </div>
    )
  }
}

class Child1 extends React.Component {
  render() {
    console.log('左侧子组件 - 1')
    return <div className="child">子组件1-1</div>
  }
}
class Child2 extends React.Component {
  render() {
    console.log('左侧子组件 - 2')
    return <div className="child">子组件1-2</div>
  }
}

// ------------------------右侧---------------------------

class Parent2 extends React.Component {
  state = {
    count: 0
  }

  handleClick = () => {
    this.setState(state => ({ count: state.count + 1 }))
  }

  render() {
    console.log('右侧父组件')
    return (
      <div className="parent">
        <h2>
          右侧 - 父组件2
          <button onClick={this.handleClick}>点我({this.state.count}</button>
        </h2>
        <div className="parent-wrapper">
          <Child3 />
          <Child4 />
        </div>
      </div>
    )
  }
}

class Child3 extends React.Component {
  render() {
    console.log('右侧子组件 - 1')
    return <div className="child">子组件2-1</div>
  }
}
class Child4 extends React.Component {
  render() {
    console.log('右侧子组件 - 2')
    return <div className="child">子组件2-2 </div>
  }
}

ReactDOM.render(<App />, document.getElementById('root'))

组件性能优化

import React from 'react'
import ReactDOM from 'react-dom'

// 生成随机数
class App extends React.Component {
  state = { number: 0 }
  handleClick = () => {
    this.setState(() => {
      return { number: Math.floor(Math.random() * 3) }
    })
  }
  // 钩子函数
  // 因为两次生成的随机数可能相同,如果相同,此时,不需要重新渲染
  shouldComponentUpdate(nextProps, nextState) {
    console.log('最新状态:', nextState, ', 当前状态:', this.state)
    return nextState.number !== this.state.number
    // 返回false,阻止组件重新渲染
  }

  render() {
    console.log('render 执行了')
    return (
      <div>
        <h1>随机数:{this.state.number}</h1>
        <button onClick={this.handleClick}>重新生成</button>
      </div>
    )
    
  }
}

ReactDOM.render(<App />, document.getElementById('root'))

import React from 'react'
import ReactDOM from 'react-dom'

// 生成随机数
class App extends React.Component {
  state = {
    number: 0
  }

  handleClick = () => {
    this.setState(() => {
      return {
        number: Math.floor(Math.random() * 3)
      }
    })
  }


  render() {
    // console.log('render')
    return (
      <div>
        <NumberBox number={this.state.number} />
        <button onClick={this.handleClick}>重新生成</button>
      </div>
    )
  }
}

class NumberBox extends React.Component {
  shouldComponentUpdate(nextProps) {
    console.log('最新props:', nextProps, ', 当前props:', this.props)
    // 如果前后两次的number值相同,就返回false,不更新组件
    return nextProps.number !== this.props.number
  }
  render() {
    console.log('子组件中的render')
    return <h1>随机数:{this.props.number}</h1>
  }
}

ReactDOM.render(<App />, document.getElementById('root'))

虚拟DOM 和 Diff算法

import React from 'react'
import ReactDOM from 'react-dom'


// 生成随机数
class App extends React.PureComponent {
  state = {
    number: 0
  }

  handleClick = () => {
    this.setState(() => {
      return {
        number: Math.floor(Math.random() * 2)
      }
    })
  }

  // render方法调用并不意味着浏览器中的重新渲染!!!
  // render方法调用仅仅说明要进行diff
  render() {
    const el = (
      <div>
        <h1>随机数:</h1>
        <p>{this.state.number}</p>
        <button onClick={this.handleClick}>重新生成</button>
      </div>
    )
    console.log(el)

    return el
  }
}

ReactDOM.render(<App />, document.getElementById('root'))

v6 路由

  • 一般的项目结构

React 学习笔记_第3张图片

  • 本案例目录结构

本案例粘贴于 github

React 学习笔记_第4张图片

  • App.js
// import { BrowserRouter as Router, Route, Routes, Link } from 'react-router-dom'
import { HashRouter as Router, Routes, Route } from 'react-router-dom';
import Home from './containers/Home/index';
import City from './containers/City/index';
import Earth from './containers/Earth/index';
import Demo from './containers/Demo/index';
import Lunar from './containers/Lunar/index';
import Cell from './containers/Cell/index';
import Car from './containers/Car/index';
import Zelda from './containers/Zelda/index';
import Metaverse from './containers/Metaverse/index';
import SegmentFault from './containers/SegmentFault/index';
import Diamond from './containers/Diamond/index';
import Human from './containers/Human/index';
import Olympic from './containers/Olympic/index';

function App() {
  return (
    <div className="App">
      <Router>
        <Routes>
          <Route element={<Home />} path="/" />
          <Route element={<City />} path="/city" />
          <Route element={<Earth />} path="/earth" />
          <Route element={<Demo />} path="/demo" />
          <Route element={<Lunar />} path="/lunar" />
          <Route element={<Cell />} path="/cell" />
          <Route element={<Car />} path="/car" />
          <Route element={<Zelda />} path="/zelda" />
          <Route element={<Metaverse />} path="/metaverse" />
          <Route element={<SegmentFault />} path="/segmentfault" />
          <Route element={<Diamond />} path="/diamond" />
          <Route element={<Human />} path="/human" />
          <Route element={<Olympic />} path="/olympic" />
        </Routes>
      </Router>
    </div>
  );
}

export default App;
  • /home/index.js
import React from 'react';
import Paper from '@mui/material/Paper';
import { styled } from '@mui/material/styles';
import Box from '@mui/material/Box';
import MediaCard from '../../components/MediaCard/index';
import Grid from '@mui/material/Grid';
import cityImage from './images/city.png';
import panoramicImage from './images/panoramic.png';
import metaImage from './images/meta.png';
import earthImage from './images/earth.png';
import cellImage from './images/cell.png';
import lunarImage from './images/lunar.png';
import zeldaImage from './images/zelda.png';
import zeldaMapImage from './images/zelda_map.png';
import scanImage from './images/scan.png';
import carImage from './images/car.png';
import developingImage from './images/developing.png';
import segmentFaultImage from './images/segmengfault.png';
import humanImage from './images/human.png';
import olympicImage from './images/olympic.png';
import './index.css';

const Item = styled(Paper)(({ theme }) => ({
  ...theme.typography.body2,
  padding: theme.spacing(1),
  textAlign: 'center',
  color: theme.palette.text.secondary,
}));

const workList = [
  {
    link: '#/city',
    title: '数字城市',
    description: ' 3D数字城市 【⚠优化中】',
    image: cityImage,
    three: true
  },
  {
    link: 'https://dragonir.github.io/3d-meta-logo/',
    title: '脸书Meta元宇宙Logo',
    description: ' Three.js + Blender 实现炫酷的Facebook元宇宙Logo.',
    image: metaImage,
    three: true
  },
  {
    link: '#/olympic',
    title: '2022冬奥会3D趣味页面',
    description: '一只萌萌的冰墩墩送给大家!',
    image: olympicImage,
    three: true
  },
  {
    link: 'https://dragonir.github.io/3d-panoramic-vision/',
    title: '全景侦探小游戏',
    description: '️‍ 使用Three.js全景功能实现侦探小游戏。',
    image: panoramicImage,
    three: true
  },
  {
    link: '#/lunar',
    title: '虎年春节创意',
    description: ' 2022虎虎生威!',
    image: lunarImage,
    three: true
  },
  {
    link: '#/segmentfault',
    title: 'SegmentFault突破1000粉纪念',
    description: ' 1000+ followers !',
    image: segmentFaultImage,
    three: true
  },
  {
    link: '#/human',
    title: 'Metahuman',
    description: ' 元宇宙数字人类【⚠优化中】',
    image: humanImage,
    three: true
  },
  {
    link: '#/earth',
    title: '地球',
    description: ' 尽情探索3D Low Poly数字地球吧!【⚠优化中】',
    image: earthImage,
    three: true
  },
  {
    link: '#/cell',
    title: '动植物细胞结构',
    description: ' 可以查看动物细胞和植物细胞的内部组成结构。【⚠优化中】',
    image: cellImage,
    three: true
  },
  {
    link: 'https://dragonir.github.io/zelda-map/',
    title: '塞尔达:旷野之息地图',
    description: ' 在地图上标记神庙、查询回忆点!',
    image: zeldaMapImage,
  },
  {
    link: 'https://dragonir.github.io/h5-scan-qrcode/',
    title: '浏览器扫码',
    description: ' 使用原生浏览器就可以在h5页面实现扫码功能了,试试看!',
    image: scanImage,
  },
  {
    link: '#/car',
    title: 'Lamborghini Centenario LP-770',
    description: '车辆模型展示【⚠优化中】',
    image: carImage,
    three: true
  },
  {
    link: '#/zelda',
    title: '塞尔达:旷野之息3D',
    description: ' 林克【⚠优化中】',
    image: zeldaImage,
    three: true
  },
  {
    link: '#/',
    title: '远航:无尽的拉格朗日',
    description: '开发中...',
    image: developingImage,
    three: true
  },
  {
    link: '#/',
    title: '探索:无人深空',
    description: '开发中...',
    image: developingImage,
    three: true
  },
  {
    link: '#/',
    title: '着陆:失落的星球',
    description: '开发中...',
    image: developingImage,
    three: true
  },
  {
    link: '#/',
    title: '航巡:迷失在黑洞',
    description: '开发中...',
    image: developingImage,
    three: true
  }
];

export default class Home extends React.Component {
  render () {
    return (
      <div className="home" style={{ padding: '24px'}}>
        <Box>
          <h1 className="page_title">dragonir's work list</h1>
        </Box>
        <Box sx={{ width: '100%' }} style={{ maxWidth: '1200px', margin: 'auto' }}>
          <Grid container rowSpacing={1} columnSpacing={{ xs: 1, sm: 2, md: 3 }}>
            {workList.map((item, index) => (
              <Grid item xs={12} sm={6} md={4} key={index}>
                <Item elevation={0} className="grid_item">
                  {item.three ? (<i className="three_logo"></i>) : '' }
                  <MediaCard link={item.link} title={item.title} image={item.image} description={item.description} />
                </Item>
              </Grid>
            ))}
          </Grid>
        </Box>
      </div>
    )
  }
}

React 学习笔记_第5张图片React 学习笔记_第6张图片React 学习笔记_第7张图片React 学习笔记_第8张图片React 学习笔记_第9张图片React 学习笔记_第10张图片React 学习笔记_第11张图片React 学习笔记_第12张图片React 学习笔记_第13张图片React 学习笔记_第14张图片

你可能感兴趣的:(WEB,#,React,react.js,javascript,前端)