示例代码:

    示例代码中用state中的loading去控制loading组件是否显示隐藏,增加了组件间的耦合,不是一种好的书写方式。

    1. import React, {Component} from 'react';
    2. import ReactDOM from 'react-dom';
    3. import './index.css';
    4. import * as serviceWorker from './serviceWorker';
    5. class Loading extends Component {
    6. render(){
    7. return (<div>
    8. loading...
    9. </div>);
    10. }
    11. }
    12. class App extends Component{
    13. constructor(props){
    14. super(props);
    15. this.state = {
    16. data: [],
    17. loading: false
    18. };
    19. }
    20. render(){
    21. return (<div>
    22. APP
    23. {this.state.data.map((item) => <div>{item}</div>)}
    24. {this.state.loading && <Loading/>}
    25. </div>);
    26. }
    27. componentDidMount(){
    28. this.setState({
    29. loading: true
    30. });
    31. setTimeout(() => {
    32. this.setState({
    33. data: ['a', 'b', 'c'],
    34. loading: false
    35. });
    36. }, 2000);
    37. }
    38. }
    39. ReactDOM.render(<App />, document.getElementById('root'));
    40. // If you want your app to work offline and load faster, you can change
    41. // unregister() to register() below. Note this comes with some pitfalls.
    42. // Learn more about service workers: https://bit.ly/CRA-PWA
    43. serviceWorker.unregister();

    对以上代码进行优化:

    定义了一个方法组件,调用方法组件的方法来实现组件的显示和隐藏。

    1. .loading {
    2. position: absolute;
    3. left: 0;
    4. right: 0;
    5. top: 0;
    6. bottom: 0;
    7. background-color: rgba(0, 0, 0, 0.3);
    8. }
    9. .loading__content {
    10. position: absolute;
    11. text-align: center;
    12. left: 0;
    13. right: 0;
    14. top: 50%;
    15. }

    动态加载组件:

    1. node = document.createElement('div');
    2. document.body.appendChild(node);
    3. ReactDOM.render(<Loading/>, node);

    卸载组件:

    1. ReactDOM.unmountComponentAtNode(node);

    优化后的代码:

    1. import React, {Component} from 'react';
    2. import ReactDOM from 'react-dom';
    3. import './index.css';
    4. import * as serviceWorker from './serviceWorker';
    5. class Loading extends Component {
    6. render(){
    7. return (<div className="loading">
    8. <div className="loading__content">
    9. loading...
    10. </div>
    11. </div>);
    12. }
    13. }
    14. let node = null;
    15. const loading = {
    16. show() {
    17. node = document.createElement('div');
    18. document.body.appendChild(node);
    19. ReactDOM.render(<Loading/>, node);
    20. },
    21. hide(){
    22. if(node) {
    23. ReactDOM.unmountComponentAtNode(node);
    24. document.body.removeChild(node);
    25. }
    26. }
    27. };
    28. class App extends Component{
    29. constructor(props){
    30. super(props);
    31. this.state = {
    32. data: []
    33. };
    34. }
    35. render(){
    36. return (<div>
    37. APP
    38. {this.state.data.map((item) => <div key={item}>{item}</div>)}
    39. </div>);
    40. }
    41. componentDidMount(){
    42. loading.show();
    43. setTimeout(() => {
    44. this.setState({
    45. data: ['a', 'b', 'c']
    46. });
    47. loading.hide();
    48. }, 2000);
    49. }
    50. }
    51. ReactDOM.render(<App />, document.getElementById('root'));
    52. // If you want your app to work offline and load faster, you can change
    53. // unregister() to register() below. Note this comes with some pitfalls.
    54. // Learn more about service workers: https://bit.ly/CRA-PWA
    55. serviceWorker.unregister();

    方法组件实例代码2:
    实际使用过程中,可以把方法组件单独放进一个文件里,然后export default inp;

    1. import React, {Component} from 'react';
    2. import ReactDOM from 'react-dom';
    3. import './index.css';
    4. import * as serviceWorker from './serviceWorker';
    5. class Input extends Component {
    6. constructor(props){
    7. super(props);
    8. this.state = {
    9. value: ''
    10. };
    11. }
    12. render(){
    13. let {
    14. onOK
    15. } = this.props;
    16. return (<div className="loading">
    17. <div className="loading__content">
    18. <input value={this.state.value} onChange={(e) => this.setState({value: e.target.value})} type='text'/>
    19. <button onClick={(e) => {
    20. onOK(this.state.value);
    21. this.setState({
    22. value: ''
    23. });
    24. inp.hide();
    25. }
    26. }>Add</button>
    27. </div>
    28. </div>);
    29. }
    30. }
    31. let node = null;
    32. const inp = {
    33. show(obj) {
    34. node = document.createElement('div');
    35. document.body.appendChild(node);
    36. ReactDOM.render(<Input onOK={obj.onOK}/>, node);
    37. },
    38. hide(){
    39. if(node) {
    40. ReactDOM.unmountComponentAtNode(node);
    41. document.body.removeChild(node);
    42. }
    43. }
    44. };
    45. class App extends Component{
    46. constructor(props){
    47. super(props);
    48. this.state = {
    49. data: []
    50. };
    51. }
    52. render(){
    53. return (<div>
    54. APP
    55. {this.state.data.map((item) => <div key={item.id}>{item.value}</div>)}
    56. </div>);
    57. }
    58. componentDidMount(){
    59. inp.show({
    60. onOK: (value) => {
    61. let { data } = this.state;
    62. data.push({
    63. id: value,
    64. value: value
    65. });
    66. this.setState({
    67. data: data
    68. });
    69. }
    70. });
    71. }
    72. }
    73. ReactDOM.render(<App />, document.getElementById('root'));
    74. // If you want your app to work offline and load faster, you can change
    75. // unregister() to register() below. Note this comes with some pitfalls.
    76. // Learn more about service workers: https://bit.ly/CRA-PWA
    77. serviceWorker.unregister();

    示例代码3:

    实现列表的增删:

    1. import React, {Component} from 'react';
    2. import ReactDOM from 'react-dom';
    3. import './index.css';
    4. import * as serviceWorker from './serviceWorker';
    5. class Action extends Component {
    6. constructor(props){
    7. super(props);
    8. this.state = {
    9. value: ''
    10. };
    11. }
    12. render(){
    13. let {
    14. onAdd
    15. } = this.props;
    16. return (<div style={{ padding: '20px'}}>
    17. <input value={this.state.value} onChange={(e) => this.setState({value: e.target.value})} type='text'/>
    18. <button onClick={(e) => {
    19. onAdd(this.state.value);
    20. this.setState({
    21. value: ''
    22. });
    23. }
    24. }>Add</button>
    25. </div>);
    26. }
    27. }
    28. class ToDoList extends Component {
    29. render(){
    30. let { data, onDel } = this.props;
    31. return (<div><ol>
    32. {
    33. data.map((item, index) =>
    34. <li key={index}>
    35. <p>{item}</p>
    36. <button onClick={(e) => {
    37. onDel(index);
    38. }}>Delete</button>
    39. </li>
    40. )}
    41. </ol>
    42. </div>);
    43. }
    44. }
    45. class App extends Component{
    46. constructor(props){
    47. super(props);
    48. this.state = {
    49. data: ['abc']
    50. };
    51. }
    52. render(){
    53. return (<div>
    54. <Action onAdd={
    55. (item) => {
    56. let data = this.state.data;
    57. data.push(item);
    58. this.setState({
    59. data
    60. });
    61. }
    62. }/>
    63. <ToDoList data={this.state.data} onDel={(index) => {
    64. let data = this.state.data;
    65. data.splice(index, 1);
    66. this.setState({ data});
    67. }}/>
    68. </div>);
    69. }
    70. componentDidMount(){
    71. }
    72. }
    73. ReactDOM.render(<App />, document.getElementById('root'));
    74. // If you want your app to work offline and load faster, you can change
    75. // unregister() to register() below. Note this comes with some pitfalls.
    76. // Learn more about service workers: https://bit.ly/CRA-PWA
    77. serviceWorker.unregister();