示例代码:
示例代码中用state中的loading去控制loading组件是否显示隐藏,增加了组件间的耦合,不是一种好的书写方式。
import React, {Component} from 'react';import ReactDOM from 'react-dom';import './index.css';import * as serviceWorker from './serviceWorker';class Loading extends Component {render(){return (<div>loading...</div>);}}class App extends Component{constructor(props){super(props);this.state = {data: [],loading: false};}render(){return (<div>APP{this.state.data.map((item) => <div>{item}</div>)}{this.state.loading && <Loading/>}</div>);}componentDidMount(){this.setState({loading: true});setTimeout(() => {this.setState({data: ['a', 'b', 'c'],loading: false});}, 2000);}}ReactDOM.render(<App />, document.getElementById('root'));// If you want your app to work offline and load faster, you can change// unregister() to register() below. Note this comes with some pitfalls.// Learn more about service workers: https://bit.ly/CRA-PWAserviceWorker.unregister();
对以上代码进行优化:
定义了一个方法组件,调用方法组件的方法来实现组件的显示和隐藏。
.loading {position: absolute;left: 0;right: 0;top: 0;bottom: 0;background-color: rgba(0, 0, 0, 0.3);}.loading__content {position: absolute;text-align: center;left: 0;right: 0;top: 50%;}
动态加载组件:
node = document.createElement('div');document.body.appendChild(node);ReactDOM.render(<Loading/>, node);
卸载组件:
ReactDOM.unmountComponentAtNode(node);
优化后的代码:
import React, {Component} from 'react';import ReactDOM from 'react-dom';import './index.css';import * as serviceWorker from './serviceWorker';class Loading extends Component {render(){return (<div className="loading"><div className="loading__content">loading...</div></div>);}}let node = null;const loading = {show() {node = document.createElement('div');document.body.appendChild(node);ReactDOM.render(<Loading/>, node);},hide(){if(node) {ReactDOM.unmountComponentAtNode(node);document.body.removeChild(node);}}};class App extends Component{constructor(props){super(props);this.state = {data: []};}render(){return (<div>APP{this.state.data.map((item) => <div key={item}>{item}</div>)}</div>);}componentDidMount(){loading.show();setTimeout(() => {this.setState({data: ['a', 'b', 'c']});loading.hide();}, 2000);}}ReactDOM.render(<App />, document.getElementById('root'));// If you want your app to work offline and load faster, you can change// unregister() to register() below. Note this comes with some pitfalls.// Learn more about service workers: https://bit.ly/CRA-PWAserviceWorker.unregister();
方法组件实例代码2:
实际使用过程中,可以把方法组件单独放进一个文件里,然后export default inp;
import React, {Component} from 'react';import ReactDOM from 'react-dom';import './index.css';import * as serviceWorker from './serviceWorker';class Input extends Component {constructor(props){super(props);this.state = {value: ''};}render(){let {onOK} = this.props;return (<div className="loading"><div className="loading__content"><input value={this.state.value} onChange={(e) => this.setState({value: e.target.value})} type='text'/><button onClick={(e) => {onOK(this.state.value);this.setState({value: ''});inp.hide();}}>Add</button></div></div>);}}let node = null;const inp = {show(obj) {node = document.createElement('div');document.body.appendChild(node);ReactDOM.render(<Input onOK={obj.onOK}/>, node);},hide(){if(node) {ReactDOM.unmountComponentAtNode(node);document.body.removeChild(node);}}};class App extends Component{constructor(props){super(props);this.state = {data: []};}render(){return (<div>APP{this.state.data.map((item) => <div key={item.id}>{item.value}</div>)}</div>);}componentDidMount(){inp.show({onOK: (value) => {let { data } = this.state;data.push({id: value,value: value});this.setState({data: data});}});}}ReactDOM.render(<App />, document.getElementById('root'));// If you want your app to work offline and load faster, you can change// unregister() to register() below. Note this comes with some pitfalls.// Learn more about service workers: https://bit.ly/CRA-PWAserviceWorker.unregister();
示例代码3:
实现列表的增删:
import React, {Component} from 'react';import ReactDOM from 'react-dom';import './index.css';import * as serviceWorker from './serviceWorker';class Action extends Component {constructor(props){super(props);this.state = {value: ''};}render(){let {onAdd} = this.props;return (<div style={{ padding: '20px'}}><input value={this.state.value} onChange={(e) => this.setState({value: e.target.value})} type='text'/><button onClick={(e) => {onAdd(this.state.value);this.setState({value: ''});}}>Add</button></div>);}}class ToDoList extends Component {render(){let { data, onDel } = this.props;return (<div><ol>{data.map((item, index) =><li key={index}><p>{item}</p><button onClick={(e) => {onDel(index);}}>Delete</button></li>)}</ol></div>);}}class App extends Component{constructor(props){super(props);this.state = {data: ['abc']};}render(){return (<div><Action onAdd={(item) => {let data = this.state.data;data.push(item);this.setState({data});}}/><ToDoList data={this.state.data} onDel={(index) => {let data = this.state.data;data.splice(index, 1);this.setState({ data});}}/></div>);}componentDidMount(){}}ReactDOM.render(<App />, document.getElementById('root'));// If you want your app to work offline and load faster, you can change// unregister() to register() below. Note this comes with some pitfalls.// Learn more about service workers: https://bit.ly/CRA-PWAserviceWorker.unregister();
