{"id":16384375,"url":"https://github.com/muyunyun/cpreact","last_synced_at":"2025-03-21T02:31:11.584Z","repository":{"id":57210241,"uuid":"139415798","full_name":"MuYunyun/cpreact","owner":"MuYunyun","description":"Build React from Scratch :tada:","archived":false,"fork":false,"pushed_at":"2018-11-15T13:20:13.000Z","size":1111,"stargazers_count":33,"open_issues_count":3,"forks_count":3,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-10-11T04:11:51.567Z","etag":null,"topics":["perfomance","preact","reactjs"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MuYunyun.png","metadata":{"files":{"readme":"README-zh_en.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-07-02T08:44:59.000Z","updated_at":"2022-04-02T14:40:50.000Z","dependencies_parsed_at":"2022-08-31T05:02:03.288Z","dependency_job_id":null,"html_url":"https://github.com/MuYunyun/cpreact","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MuYunyun%2Fcpreact","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MuYunyun%2Fcpreact/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MuYunyun%2Fcpreact/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MuYunyun%2Fcpreact/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MuYunyun","download_url":"https://codeload.github.com/MuYunyun/cpreact/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221811386,"owners_count":16884305,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["perfomance","preact","reactjs"],"created_at":"2024-10-11T04:11:16.729Z","updated_at":"2024-10-28T09:07:29.894Z","avatar_url":"https://github.com/MuYunyun.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"http://oqhtscus0.bkt.clouddn.com/9c461a61924ed0fecb6024a256671251.jpg-200\"\u003e\n\u003c/div\u003e\n\n[![npm version](https://badge.fury.io/js/cpreact.svg)](https://badge.fury.io/js/cpreact) ![LICENSE MIT](https://img.shields.io/npm/l/express.svg)\n\nThis proj is aim to implement react from 0 to 1. In the meantime the develop experience is writen down as a series of articles as follow:\n\n- [x] [前置准备](https://github.com/MuYunyun/blog/blob/master/从0到1实现React/0.前置准备.md)\n- [x] [JSX 和 Virtual DOM](https://github.com/MuYunyun/blog/issues/24)\n- [x] [组件和 state|props](https://github.com/MuYunyun/blog/issues/25)\n- [x] [生命周期](https://github.com/MuYunyun/blog/blob/master/从0到1实现React/3.生命周期.md)\n- [x] [diff 算法](https://github.com/MuYunyun/blog/issues/26)\n- [x] [setState 优化](https://github.com/MuYunyun/blog/blob/master/从0到1实现React/5.setState.md)\n- [x] [ref 的实现](https://github.com/MuYunyun/blog/blob/master/从0到1实现React/6.ref.md)\n- [x] [PureComponent 的实现](https://github.com/MuYunyun/blog/blob/master/从0到1实现React/7.PureComponent.md)\n- [x] [HOC 探幽](https://github.com/MuYunyun/blog/blob/master/从0到1实现React/8.HOC探索.md)\n- [ ] 事件机制探索\n\nYou can view the [release](https://github.com/MuYunyun/cpreact/releases) to find the corresponding code synced with the article.\n\n### Useful Demos\n\nThere are some useful test cases from the develop experience. I've collected them as follow:\n\n\u003cdetails\u003e\n  \u003csummary\u003ecomponents\u003c/summary\u003e\n\n```js\nclass App extends Component {\n  constructor(props) {\n    super(props)\n    this.state = {\n      count: 1\n    }\n  }\n\n  click() {\n    this.setState({\n      count: ++this.state.count\n    })\n  }\n\n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003cbutton onClick={this.click.bind(this)}\u003eClick Me!\u003c/button\u003e\n        \u003cdiv\u003e{this.state.count}\u003c/div\u003e\n      \u003c/div\u003e\n    )\n  }\n}\n\nReactDOM.render(\n  \u003cApp name=\"count\" /\u003e,\n  document.getElementById('root')\n)\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003estate \u0026\u0026 props\u003c/summary\u003e\n\n```js\n// this case is to know the attr in the jsx `\u003cA a={1} { ...obj } /\u003e` is converted to { a: 1, b: 2, c: 3 }\n\nclass A extends Component {\n  render() {\n    return (\n      \u003cdiv\u003e{this.props.a + this.props.b + this.props.c}\u003c/div\u003e\n    )\n  }\n}\n\nclass B extends Component {\n  render() {\n    const obj = { b: 2, c: 3 }\n    return (\n      \u003cdiv\u003e\n        \u003cA a={1} { ...obj } /\u003e\n      \u003c/div\u003e\n    )\n  }\n}\n\nReactDOM.render(\n  \u003cB /\u003e,\n  document.getElementById('root')\n)\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003elife cycle\u003c/summary\u003e\n\n```js\nclass A extends Component {\n  componentWillReceiveProps(props) {\n    console.log('componentWillReceiveProps')\n  }\n\n  render() {\n    return (\n      \u003cdiv\u003e{this.props.count}\u003c/div\u003e\n    )\n  }\n}\n\nclass B extends Component {\n  constructor(props) {\n    super(props)\n    this.state = {\n      count: 1\n    }\n  }\n\n  componentWillMount() {\n    console.log('componentWillMount')\n  }\n\n  componentDidMount() {\n    console.log('componentDidMount')\n  }\n\n  shouldComponentUpdate(nextProps, nextState) {\n    console.log('shouldComponentUpdate', nextProps, nextState)\n    return true\n  }\n\n  componentWillUpdate() {\n    console.log('componentWillUpdate')\n  }\n\n  componentDidUpdate() {\n    console.log('componentDidUpdate')\n  }\n\n  click() {\n    this.setState({\n      count: ++this.state.count\n    })\n  }\n\n  render() {\n    console.log('render')\n    return (\n      \u003cdiv\u003e\n        \u003cbutton onClick={this.click.bind(this)}\u003eClick Me!\u003c/button\u003e\n        \u003cA count={this.state.count} /\u003e\n      \u003c/div\u003e\n    )\n  }\n}\n\nReactDOM.render(\n  \u003cB /\u003e,\n  document.getElementById('root')\n)\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003esetState\u003c/summary\u003e\n\n```js\nclass B extends Component {\n  constructor(props) {\n    super(props)\n    this.state = {\n      count: 0\n    }\n    this.click = this.click.bind(this)\n  }\n\n  click() {\n    for (let i = 0; i \u003c 10; i++) {\n      this.setState({ // 在先前的逻辑中，没调用一次 setState 就会 render 一次\n        count: ++this.state.count\n      })\n    }\n  }\n\n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003cbutton onClick={this.click}\u003e增加\u003c/button\u003e\n        \u003cdiv\u003e{this.state.count}\u003c/div\u003e\n      \u003c/div\u003e\n    )\n  }\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eref\u003c/summary\u003e\n\n```js\nclass A extends Component {\n  constructor() {\n    super()\n    this.state = {\n      count: 0\n    }\n    this.click = this.click.bind(this)\n  }\n\n  click() {\n    this.setState({\n      count: ++this.state.count\n    })\n  }\n\n  render() {\n    return \u003cdiv\u003e{this.state.count}\u003c/div\u003e\n  }\n}\n\nclass B extends Component {\n  constructor() {\n    super()\n    this.click = this.click.bind(this)\n  }\n\n  click() {\n    this.A.click()\n  }\n\n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003cbutton onClick={this.click}\u003e加1\u003c/button\u003e\n        \u003cA ref={(e) =\u003e { this.A = e }} /\u003e\n      \u003c/div\u003e\n    )\n  }\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003ePureComponent\u003c/summary\u003e\n\n```js\n// 测试用例：验证 state 浅比较\nclass B extends PureComponent {\n  constructor(props) {\n    super(props)\n    this.state = {\n      count: 0\n    }\n    this.click = this.click.bind(this)\n  }\n\n  click() {\n    const state = Object.assign({}, this.state)\n\n    this.setState({\n      count: this.state.count + 1,\n    })\n  }\n\n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003cbutton onClick={this.click}\u003e增加\u003c/button\u003e\n        \u003cdiv\u003e{this.state.count}\u003c/div\u003e\n      \u003c/div\u003e\n    )\n  }\n}\n\n// 测试用例：验证 props 浅比较\nclass A extends PureComponent {\n  render() {\n    return (\n      \u003cdiv\u003e{this.props.count.number}\u003c/div\u003e\n    )\n  }\n}\n\nclass B extends PureComponent {\n  constructor(props) {\n    super(props)\n    this.state = {\n      count: { number: 1 }\n    }\n  }\n\n  click() {\n    this.setState({\n      count: { number: 1 }\n    })\n  }\n\n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003cbutton onClick={this.click.bind(this)}\u003eClick Me!\u003c/button\u003e\n        \u003cA count={ this.state.count } /\u003e\n      \u003c/div\u003e\n    )\n  }\n}\n```\n\u003c/details\u003e\n\n### Install\n\n* Install with `yarn add cpreact`\n* Then you can use it in your toy proj.(Not use in the production enviroment!!!)\n\n### Thanks\n\nEspecially thank [simple-react](https://github.com/hujiulong/simple-react) for the guidance function of this library. At the meantime，respect for [preact](https://github.com/developit/preact) and [react](https://github.com/facebook/react)\n\nIf you want to contrubute this proj, you can read [how to pr](https://github.com/MuYunyun/cpreact/blob/master/.github/PULL_REQUEST_TEMPLATE.md). Thanks!","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmuyunyun%2Fcpreact","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmuyunyun%2Fcpreact","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmuyunyun%2Fcpreact/lists"}