分类 React 下的文章

Flux和Redux基本思路

Flux和Redux的基本思路都是单向数据流,但是说单项数据流太抽象了,还是说得简单易懂:
本来在Flux提出之前,大家在DOM里面直接写业务逻辑,方便快捷。
但是问题也有,比如Facebook的团队发现的诡异的小红点的问题。
那么如何解决,那就是DOM中进行操作之后触发一个请求,这个请求再被分发器dispatch到业务逻辑。

那么这样有什么好处呢?
这样系统中的所有可用的请求都做成清单,一目了然。
所有触发的请求都会经过一次Dispatcher,简洁明了。
只有Dispatcher才能接触业务逻辑,这也就是单向数据流这个词的来源。

一句话,DOM不能直接改Model了,需要触发一个请求,Dispatcher接受到请求再执行业务逻辑。

React的路由模块设计

如果从React的角度设计路由的话,其实还是比较简单的。
比如如果点击一个链接触发一个新的路由,那么你可以在这个链接写上这样的触发事件:

在Flux中添加Action:

updateURL(new_url) {
    Dispatcher.dispatch({ type: 'UPDATE_URL', url});
}

添加一个存储URL的Store

getInitialState() {
    return '/';
}

reduce(state, action) {
    switch(action.type) {
        case 'UPDATE_URL':
            return action.url;
    }
}

在Flux Container引入事件:

onUpdateUrl: TodoActions.updateURL,

在View视图中触发事件:

<a onClick={props.onUpdateUrl('/myURL')} />

在顶部Component之上添加路由Component:

function Router(props) {
    if(props.url == '/') {
        return (<App1 {...props} />);
    }
    if(props.url == '/myURL') {
        return (<App2 {...props} />);
    }
    return (<NotFound {...props} />);
}

当然,这样是最简单的方案,但是实际中肯定不会用触发点击事件的方式去实现更改URL,而是直接给<a>标签一个href,然后用户点击href,被事件系统拦截到了然后自动被分配一个Action,然后被dispatcher进行dispatch。

还有,用户直接复制url访问的问题,此时就需要系统在系统启动时检查一下当前的url是多少,然后在getInitial中获取当前url。

另外,还有一个古老的问题,就是把访问历史要记得添加到history里面去。

最后,还有一点疑问,就是用户手动修改url可以被拦截到么?是不是就可以避免重新加载。

React入门思路

首先我们来看一段代码:

var element1 = React.DOM.h1({id: "myH1"}, 'content');
ReactDOM.render(
  element1,
  document.getElementById('test1')
);

上面这段代码相信大家都看得懂吧!React有一个关键在于把所有DOM Element都用Virtual Element进行声明,然后就可以把Virtual Element用ReactDOM渲染出来。然后我们来看渲染嵌套的Virtual Element的方法:

var element2 = React.DOM.h1({id: "myH1"}, 
    React.DOM.span({id:"mySpan"}, 'span content'),
    'content');
ReactDOM.render(
  element2,
  document.getElementById('test2')
);

Virtual Element嵌套Virtual Element应该不是很难理解,毕竟DOM Element也是这样一环嵌一环的嵌套的。
这边通过嵌套Virtual Element产生了一个组合Element,但是如果我多处需要这个组合Element的话,每次都得写一遍创建代码,岂不是麻烦死了。
React里面因此诞生了Component的概念,Component和组合Elemnent的关系类似OOP中类和对象的关系。
不过首先!我们换一种新的方式来取代React.DOM.*来产生Element,来看下面代码:

var element2 = React.createElement("h1",{id: "myH1"}, 
    React.createElement("span", {id:"mySpan"}, 'span content'),
    'content');
ReactDOM.render(
  element2,
  document.getElementById('test2')
);

上面的代码仅仅是替换了React.DOM.为React.createElemnet(),但是这种方式更具有适普性,如果我们自定义了component,那么也可以通过这种方式产生Element。
行,那么我们就可以尝试搭建Component了,见如下代码:

var element2 = React.createElement("h1",{id: "myH1"}, 
    React.createElement("span", {id:"mySpan"}, 'span content'),
    'content');
var component3 = React.createClass({
    render: function() {
        return React.createElement("h1",{id: "myH1"}, 
            React.createElement("span", {id:"mySpan"}, 'span content'),
            'content');
    }
});
var element3 = React.createElement(component3);
ReactDOM.render(
  element2,
  document.getElementById('test2')
);

看了上面的代码,关于为什么要有React.createElement和React.createClass的由来想必都有所思路了吧。