书签 分享 收藏 举报 版权申诉 / 15

类型如何在使用 Flux 时使 ReactJS 更好地发挥作用.docx

  • 文档编号:3816442
  • 上传时间:2022-11-25
  • 格式:DOCX
  • 页数:15
  • 大小:120.63KB
 

14.        ) 

15.    } 

16.}); 

TodoCount组件负责显示items的计数。

它从TodoHeader组件获取计数。

1.var TodoCount = React.createClass({ 

2.    render:

 function() { 

3.        return (  

4.          

 { this.props.count } 
) 

5.    } 

6.}); 

TodoHeader组件显示应用程序的头,它调用TodoCount组件显示所有items的计数。

1.var TodoHeader = React.createClass({ 

2.    render:

 function() { 

3.        return (  

4.          

 

9.        ) 

10.    } 

11.}) 

下面是TodoForm组件。

我们同样关注它是因为除了渲染之外它还要创建数据。

handleSubmit方法在单击提交按钮时调用,它调用从Application组件获取的TodoSubmit方法。

我当时有一些疑问:

∙为什么要用这个方法?

∙为什么Application组件提交表单而不是TodoForm?

原因是Application组件是所有组件的父/祖父组件。

并且数据流是从父组件到子组件的并且子组件不能改变父组件的状态。

此外,同级组件之间不能有任何通信数据流。

现在如果TodoForm要提交表单,那么这些信息要如何传递到TodoList或TodoHeader组件?

这就是为什么要让Application组件负责提交表单。

1.var TodoForm = React.createClass({ 

2.    getInitialState:

 function() { 

3.        console.log("inside todo form of initial") 

4.        return { user:

 '', task:

 '' } 

5.    }, 

6.    handleUserChange:

 function(e) { 

7.        this.setState({ user:

 e.target.value }) 

8.    }, 

9.    handleTaskChange:

 function(e) { 

10.        this.setState({ task:

 e.target.value }) 

11.    }, 

12.    handleSubmit:

 function(e) { 

13.        e.preventDefault(); 

14.        this.props.onTodoSubmit({ user:

 this.state.user, task:

 this.state.task }) 

15.        this.setState({ user:

 '', task:

 '' }) 

16.    }, 

17.    render:

 function() { 

18.        return (  

19.           

20.                  

21.            value = { this.state.user } onChange = { this.handleUserChange } />  

22.                  

23.            value = { this.state.task } 

24.              onChange = { this.handleTaskChange } /> 

25.                   

26.           

27.        ) 

28.    } 

29.}) 

应用组件是所有组件的父组件。

于是它涉及的方法需要讨论一下。

loadDataFromServer–它会从服务器加载数据,但在例子中没有任何服务器,所以就将数据硬编码了。

handleTodoSubmit–这个方法将由TodoForm调用,就像TodoForm组件中讲解的那要。

当这个方法被调用时,它将随着新创建的Todoitem改变状态,这个新的Todoitem会触发Application组件的重新渲染,并且所有子组件将随着新的信息而更新。

1.var TODO = React.createClass({ 

2.    getInitialState:

 function() { 

3.        return { data:

 [] } 

4.    }, 

5.    loadDataFromServer:

 function() { 

6.        this.setState({ 

7.            data:

 [ 

8.              { id:

 1, user:

 "Adam", task:

 "This is task1"}, 

9.              { id:

 2, user:

 "Ricky",task:

 "This is task2"} 

10.            ] 

11.        }) 

12.    }, 

13.    componentDidMount:

 function() { 

14.        this.loadDataFromServer() 

15.    }, 

16.    handleTodoSubmit:

 function(todo) { 

17.        todo.id = Date.now() 

18.        var todos = this.state.data 

19.        var newTodos = todos.concat([todo]) 

20.        this.setState({ 

21.            data:

 newTodos 

22.        }) 

23.    }, 

24.    render:

 function() { 

25.        return (  

26.           

27.              

28.              

29.            < TodoList data = { this.state.data } />  

30.          

 

31.        ) 

32.    } 

33.}) 

34.ReactDOM.render( < TODO /> , document.getElementById("example")) 

可以看到,如果同级组件想要彼此通信,就需要将数据传递到它们的父组件。

像是例子中的TodoForm想告知TodoList有新的item被添加了。

这就是为什么Application组件传递回调方法handleTodoSubmit。

所以在TodoForm提交时它通过回调调用Application组件的handleTodoSubmit方法。

而handleTodoSubmit正在更新Application的状态,这使得通过更新TodoItem和TodoHeader来重新渲染Application组件。

在例子中,只有1个层级,但在实时情况下,可能有多个层级,而最内层的子层想要更新其他层的最内层子层。

这就需要传递的回调方法覆盖所有层级。

但这会使其不易维护,也大大降低可读性,这也使React的优势大打折扣。

现在试试相同的应用使用Flux

正如我们所看到的,Flux有4层。

根据它的这个结构编写一个代码。

Action

Actions被Views调用。

如果View要在Store中更新数据,则View会告知Action这个变更。

这里创建了AppAction。

在这里,只有一个action,即addItem。

当要添加一个新的todoItem时,这将会被调用。

这个action进一步调用dispatcher(AppDispatcher)的handleViewAction。

1.var AppDispatcher = require('../dispatchers/app-dispatcher'); 

2.var AppAction = { 

3.    addItem:

 function(item) { 

4.        AppDispatcher.handleViewAction({ 

5.            actionType:

 'ADD_ITEM', 

6.            item:

 item 

7.        }) 

8.    } 

9.} 

Dispatcher

在AppDispatcher中,定义了由AppLIcation调用的handleViewAction。

在handleViewAction中,action会被传递用做告知执行什么action。

handleViewAction里面有一个this.dispatch,这是一个Dispatcher的预定义方法。

这个方法会在内部调用Store。

1.var Dispatcher = require("flux").Dispatcher;  

2.var assign = Object.assign;  

3.var AppDispatcher = assign(new Dispatcher(), {  

4.handleViewAction:

 function(action) {  

5.console.log('action', action)  

6.this.dispatch({  

7.source:

 'VIEW_ACTION',  

8.action:

 action  

9.})  

10.}  

11.}); 

Store(存储)

接下来我们一个个地讨论Store的方法。

dispatcherIndex–由于AppDispatcher.register,执行从这里开始。

每当调用Dispatcher的dispatch方法时,它会在所有定义AppDispatcher.register的地方传递action的信息。

在例子中,只有一个action——“ADD_ITEM”,但在大多数情况下,将有多个action。

因此,需要首先定义action的类型,基于此,还会执行actions并调用emit方法。

这里,在dispatcherIndex方法中调用addTodoItem方法,之后是调用emitChange。

addTodoItem–在这个方法中,除了将新的todoitem添加到到todoItems数组不会做其它事情。

emitChange–在emitChange中,使用this.emit(CHANGE_EVENT)方法可以允许CHANGE_EVENT的监听者知道某些东西发生了变化。

addListener–Views用这个方法来监听CHANGE_EVENT。

removeListener–Views用这个方法来移除监听器。

getTodoItems–这个方法会返回所有的todos。

它会被TodoList组件调用。

getTodoCount–这个方法会返回所有todos的计数。

它会被TodoCount组件调用。

component.

1.var AppDispatcher = require('../dispatchers/app-dispatcher'); 

2.var assign = Object.assign; 

3.var EventEmitter = require('events').EventEmitter; 

4.var CHANGE_EVENT = 'change'; 

5.var todoItems = [ 

6.  { id:

 1, user:

 "Adam", task:

 "This is task1"}, 

7.  { id:

 2, user:

 "Ricky", task:

 "This is task2"} 

8.]; 

9.var AppStore = assign(EventEmitter.prototype, { 

10.    emitChange:

 function() { 

11.        this.emit(CHANGE_EVENT) 

12.    }, 

13.    addListener:

 function(callback) { 

14.        this.on(CHANGE_EVENT, callback) 

15.    }, 

16.    removeChangeListener:

 function(callback) { 

17.        this.removeListener(CHANGE_EVENT, callback) 

18.    }, 

19.    dispatcherIndex:

 AppDispatcher.register(function(payload) { 

20.        var action = payload.action; 

21.        if (action.actionType == "ADD_ITEM") { 

22.            this.addTodoItem(payload.action.item); 

23.        } 

24.        AppStore.emitChange(); 

25.        return true; 

26.    }), 

27.    getTodoItems:

 function() { 

28.        return todoItems; 

29.    }, 

30.    getTodoCount:

 function() { 

31.        return todoItems.length; 

32.    }, 

33.    addTodoItem:

 function(todo) { 

34.        todoItems.push(todo); 

35.    } 

36.}) 

View(视图)/Components(组件)

在TodoTask中,与上面的例子一样没有改变任何东西。

1.var TodoTask = React.createClass({ 

2.    render:

 function() { 

3.        return (  

4.          

  •  { this.props.user } - { this.props.task } 
  •  

    5.        ) 

    6.    } 

    7.}) 

    在TodoList组件中,通过在getInitialState中调用AppStore.getTodoItems直接从Store提取todoitems。

    现在的问题是,“这个组件怎样才能知道新的todoitem是什么时候添加的?

    答案就在componentWillMount中。

    在这个方法中,调用AppStore.addChangeListener,它监听在Store的addChangeListener中定义的事件。

    如果有任何更改,那么它将调用_onChange来重置状态。

    1.var TodoList = React.createClass({ 

    2.    getInitialState:

     function() { 

    3.        return { todoItems:

     AppStore.getTodoItems() } 

    4.    }, 

    5.    componentWillMount:

     function() { 

    6.        AppStore.addChange

    配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    如何在使用 Flux 时使 ReactJS 更好地发挥作用 如何 使用 更好 发挥作用
    提示  冰豆网所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:如何在使用 Flux 时使 ReactJS 更好地发挥作用.docx
    链接地址:https://www.bdocx.com/doc/3816442.html
    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    copyright@ 2008-2022 冰点文档网站版权所有

    经营许可证编号:鄂ICP备2022015515号-1

    收起
    展开