多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## 声明式 React 可以无痛的创建交互UIs。在你的应用中每个状态设计简单的视图,当数据改变的时候,React 可以高效的更新和渲染正确的组件。 声明式视图使你的代码更加可预测和容易调试。 ## 基于组件 构建管理它们自己状态的组件的封装,然后用它们组成复杂的UIs 。 由于组件逻辑是使用 JavaScript 编写而不是模板,你可以通过 app 传递丰富的数据并在 DOM 外保持状态。 ## 一处学习,处处编写 我们没有假定你其余的技术栈,所以你可以在 React 中开发新的功能而不用重写已有代码。 React 也可以使用 node 在服务器端渲染,也可以通过 [React native](https://facebook.github.io/react-native/) 提供对移动 app 的支持。 ## 一个简单的组件实例 React 组件实现了一个 render() 方法,获取输入数据并返回要显示的内容。这个例子使用一个 XML 类似的语法,称为 JSX。被传递到组件的输入数据,可以通过 this.props 被 render() 访问。 JSX 是可选的,并不是使用 React 必须的选项。可以看看编译后的 JS 来查看 JSX 编译器生成的源 JavaScript 代码。 JSX代码: ~~~ class HelloMessage extends React.Component { render() { return <div> Hello {this.props.name}</div> } } ReactDom.render(<HelloMessage name="John" />, mountNode) ~~~ 编译后的JS: ~~~ class HelloMessage extends React.Component { render() { return React.createElement( "div", null, "Hello ", this.props.name ); } } ReactDOM.render(React.createElement(HelloMessage, { name: "John" }), mountNode); ~~~ ## 一个有状态的组件实例 除了获取输入数据(通过 this.props 访问),组件还可以维护内部的状态数据(通过 this.state 访问)。当一个组件的状态数据发生变化,渲染的标记会通过重新调用 render() 被更新。 JSX代码: ~~~ class Timer extends React.Component { constructor(props) { super(props) this.state = {secondsElapsed : 0} } tick() { this.setState( (prevState)=>({ secondsElapsed: prevState.secondsElapsed + 1 }) ) } componentDidMount(){ this.interval = setInterval(()=>this.tick(), 1000) } componentWillMount(){ clearInterval(this.interval) } render(){ return ( <div>Seconds elapsed: {this.state.secondsElapsed}</div> ) } } ReactDOM.render(<Timer />, mountNode) ~~~ 编译后的JS: ~~~ class Timer extends React.Component { constructor(props) { super(props); this.state = { secondsElapsed: 0 }; } tick() { this.setState(prevState => ({ secondsElapsed: prevState.secondsElapsed + 1 })); } componentDidMount() { this.interval = setInterval(() => this.tick(), 1000); } componentWillUnmount() { clearInterval(this.interval); } render() { return React.createElement( "div", null, "Seconds Elapsed: ", this.state.secondsElapsed ); } } ReactDOM.render(React.createElement(Timer, null), mountNode); ~~~ ## 一个应用实例 使用 props 和 state ,我们可以组合成一个小型的 Todo 应用。这个例子使用 state 跟踪当前项的列表和用户已经键入的文本。虽然事件处理程序出现被内联渲染,它们会被事件委托修正和实现。 JSX代码: ~~~ class TodoApp extends React.Component { constructor(props){ super(props) this.handleChange = this.handleChange.bind(this) this.handleSubmit = this.handleSubmit.bind(this) this.state = { items:[], text:''} } render(){ return( <div> <h3>TODO</h3> <TodoList items={this.state.items} /> <form onSubmit={this.handleSubmit}> <input onChange={this.handleChange} value={this.state.text} /> <button>{'Add #' + (this.state.items.length + 1)}</button> </form> </div> ) } handleChange(e){ this.setState({text:e.target.value}) } handleSubmit(e){ e.preventDefault() let newItem = { text:this.state.text, id:Date.now() } this.setState((prevState)=>({ items:prevState.items.concat(newItem), text:'' })) } } class TodoList extends React.Component { render(){ return ( <ul> {this.props.items.map(item=>( <li key={item.id}>{item.text} </li> ))} </ul> ) } } ReactDOM.render(<TodoApp />, document.getElementById('mount-node')) ~~~ JS代码: ~~~ class TodoApp extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); this.state = { items: [], text: '' }; } render() { return React.createElement( 'div', null, React.createElement( 'h3', null, 'TODO' ), React.createElement(TodoList, { items: this.state.items }), React.createElement( 'form', { onSubmit: this.handleSubmit }, React.createElement('input', { onChange: this.handleChange, value: this.state.text }), React.createElement( 'button', null, 'Add #' + (this.state.items.length + 1) ) ) ); } handleChange(e) { this.setState({ text: e.target.value }); } handleSubmit(e) { e.preventDefault(); var newItem = { text: this.state.text, id: Date.now() }; this.setState(prevState => ({ items: prevState.items.concat(newItem), text: '' })); } } class TodoList extends React.Component { render() { return React.createElement( 'ul', null, this.props.items.map(item => React.createElement( 'li', { key: item.id }, item.text )) ); } } ReactDOM.render(React.createElement(TodoApp, null), mountNode); ~~~ ## 一个使用外部插件的组件 React 非常灵活,提供了你跟其它库和框架交互的钩子。这个例子使用了 remarkable,一个外部的 Markdown 库,来实时转换 textarea 的值。 JSX代码: ~~~ class MarkdownEditor extends React.Component { constructor(props){ super(props) this.handleChange = this.handleChange.bind(this) this.state = {value:'Type some *markdown* here !'} } handleChange(){ this.setState({value:this.refs.textarea.value}) } getRawMarkup(){ let md = new Remarkable() return {__html:md.render(this.state.value)} } render(){ return ( <div className="MarkdownEditor"> <h3>Input</h3> <textarea onChange={this.handleChange} ref="textarea" defaultValue={this.state.value}></textarea> <h3>Output</h3> <div className="content" dangerouslySetInnerHTML={this.getRawMarkup()}></div> </div> ) } } ReactDOM.render(<MarkdownEditor />, document.getElementById('mount-node')) ~~~ JS 代码: ~~~ class MarkdownEditor extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = { value: 'Type some *markdown* here!' }; } handleChange() { this.setState({ value: this.refs.textarea.value }); } getRawMarkup() { var md = new Remarkable(); return { __html: md.render(this.state.value) }; } render() { return React.createElement( "div", { className: "MarkdownEditor" }, React.createElement( "h3", null, "Input" ), React.createElement("textarea", { onChange: this.handleChange, ref: "textarea", defaultValue: this.state.value }), React.createElement( "h3", null, "Output" ), React.createElement("div", { className: "content", dangerouslySetInnerHTML: this.getRawMarkup() }) ); } } ReactDOM.render(React.createElement(MarkdownEditor, null), mountNode); ~~~