• React学习笔记----如何html页面中使用react 一、ReactJS简介 React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站。做...

    React学习笔记----如何在html页面中使用react

    一、ReactJS简介

    React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了。由于 React 的设计思想极其独特,属于革命性创新,性能出众,代码逻辑却非常简单。所以,越来越多的人开始关注和使用,认为它可能是将来 Web 开发的主流工具。

    ReactJS官网地址:http://facebook.github.io/react/

    Github地址:https://github.com/facebook/react

    二、对ReactJS的认识及ReactJS的优点

    首先,对于React,有一些认识误区,这里先总结一下:

    • React不是一个完整的MVC框架,最多可以认为是MVC中的V(View),甚至React并不非常认可MVC开发模式;

    • React的服务器端Render能力只能算是一个锦上添花的功能,并不是其核心出发点,事实上React官方站点几乎没有提及其在服务器端的应用;

    • 有人拿React和Web Component相提并论,但两者并不是完全的竞争关系,你完全可以用React去开发一个真正的Web Component;

    • React不是一个新的模板语言,JSX只是一个表象,没有JSX的React也能工作。

    三、构建一个最简单的react页面

    为了快速的说明效果,我们先使用其他人的服务器(cdn服务器)进行创建一个页面,如下面代码所示:

    <!DOCTYPE html><html>
    <head>
        <meta charset="utf-8" />
        <title>React Tutorial</title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react-dom.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
    </head>
    <body>
    <div id="content"></div>
    <script type="text/babel">
        var MessageBox = React.createClass({
            alertMe: function(){
                alert('你刚才点了我一下。。。。');
            },
            render:function(){
                return ( <h1 onClick={this.alertMe}>你好世界!!!</h1> )
            }
        });
    
        React.render( <MessageBox/>,
            document.getElementById('app'),
            function(){
                console.log('渲染完成啦!!');
            }
        )
    </script>
    <div id="app"></div>
    
    </body>
    </html>
    我们通过下面三段代码进行了对react的引用

        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react-dom.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>

    也就是说,这样我们就可以直接使用了,效果如下面所示:


    上面就是使用了远端服务器提供的js库,那么如何使用我们自己下载到本地的JS库,下面就进行介绍:

    需要进行的工作有下面步骤:

       1、安装nodejs,对于nodejs的安装,请参考如下链接:nodejs的安装

       2、全局安装bower:npm install -g bower

       3、使用bower安装react:bower install react,安装过程如下图所示:



      4、使用bower安装能够将JSX 语法转为 JavaScript 语法的工具babel:bower install   babel



      5、然后开始进行页面的编写:如下所示:

    <html>
    <head>
        <meta charset="utf-8">
        <title>学习React!!</title>
    </head>
    <body>
        <div id="app"></div>
        <script src="bower_components/react/react.js"></script>
        <script src="bower_components/react/react-dom.js"></script>
      <!--  注意下面注释掉的的方式是旧版本所使用的编译转换方式,没有注释的是现在使用的-->
        <script src="bower_components/babel/browser.js"></script>
        <!--<script src="bower_components/react/JSXTransformer.js"></script>-->
        <!--<script type="text/jsx">-->
    	<script type="text/babel">
    /*		var MessageBox = React.createClass({
    			alertMe: function(){
    				alert('你刚才点了我一下。。。。');
    			},
    			render:function(){
    				return ( <h1 onClick={this.alertMe}>你好世界!!!</h1> )
    			}
    		});
    		React.render( <MessageBox/>,document.getElementById('app'),	function(){
    				console.log('渲染完成啦!!');
    			}
    		)*/
          class MessageBox extends React.Component {
              alertMe() {
                  alert('你刚才点了我一下。。。。');
              }
              render() {
                  return ( <h1 onClick={this.alertMe}>你好世界!!!</h1> )
              }
          }
          ReactDOM.render( <MessageBox/>,document.getElementById('app'),	function(){
                console.log('渲染完成啦!!');
                  });
    	</script>
    </body>
    </html>
    其点击后的效果如下图所示:



    以上就是在页面中使用react的方法


    展开全文
  • 在react中使用富文本编辑器 react+wangEditor前言第一步第二步第三步第四步第五步完整代码写最后 前言 近日使用react写项目的过程中需要使用到富文本编辑器,之前使用的一直是百度富文本框,这次想换一个,于是...

    在react中使用富文本编辑器 react+wangEditor

    前言

    近日在使用react写项目的过程中需要使用到富文本编辑器,之前使用的一直是百度富文本框,这次想换一个,于是看到了一个比较轻量级的富文本编辑器:wangeditor ,正好也满足我当前所需要的需求,所以就决定使用这款编辑器了。这篇文章给了我很大的帮助,感谢作者:react中引入富文本编辑器wangeditor,react打包项目直接运行文件,话不多说,进入正题

    第一步

    先npm导入wangEditor:

    npm install wangeditor --save
    

    第二步

    引入wangeditor包:

    import E from 'wangeditor'
    

    第三步

    创建render函数:

    render() {
            return (
                <div className="shop">
                    <div className="text-area" >
                        <div ref="editorElemMenu"
                             style={{backgroundColor:'#f1f1f1',border:"1px solid #ccc"}}
                             className="editorElem-menu">
    
                        </div>
                        <div
                            style={{
                                padding:"0 10px",
                                overflowY:"scroll",
                                height:300,
                                border:"1px solid #ccc",
                                borderTop:"none"
                            }}
                            ref="editorElemBody" className="editorElem-body">
    
                        </div>
                    </div>
                </div>
            );
        }
    

    第四步

        constructor(props) {
            super(props);
            this.state = {
                editorContent:''
             };
        }
    

    第五步

    在组件渲染完毕(componentDidMount)之后实例化编辑器:

    componentDidMount() {
            const elemMenu = this.refs.editorElemMenu;
            const elemBody = this.refs.editorElemBody;
            const editor = new E(elemMenu,elemBody)
            // 使用 onchange 函数监听内容的变化,并实时更新到 state 中
            editor.customConfig.onchange = html => {
                console.log(editor.txt.html())
                this.setState({
                    // editorContent: editor.txt.text()
                    editorContent: editor.txt.html()
                })
            }
            editor.customConfig.menus = [
                'head',  // 标题
                'bold',  // 粗体
                'fontSize',  // 字号
                'fontName',  // 字体
                'italic',  // 斜体
                'underline',  // 下划线
                'strikeThrough',  // 删除线
                'foreColor',  // 文字颜色
                'backColor',  // 背景颜色
                'link',  // 插入链接
                'list',  // 列表
                'justify',  // 对齐方式
                'quote',  // 引用
                'emoticon',  // 表情
                'image',  // 插入图片
                'table',  // 表格
                'video',  // 插入视频
                'code',  // 插入代码
                'undo',  // 撤销
                'redo'  // 重复
            ]
            editor.customConfig.uploadImgShowBase64 = true
            editor.create()
        };
    

    注意点一:
    此处需要十分注意的是 editor.customConfig.menus 这个属性设置,这个属性是配置你的富文本编辑器所需要的功能的,如果不配置的话,那么界面就不会有上面的加粗斜体上传图片之类的功能条了,当然,如果你不需要这么多功能的话,也可以注释掉一部分。
    注意点二:
    editor.customConfig.uploadImgShowBase64 = true 这个属性是配置当前是否需要设置上传图片在前端转换成base64的,如果你当前对接的模式是需要先上传图片到自己的服务器上的话,那么请查看官方文档,文档内有相关代码:

        editor.customConfig.uploadImgServer = 'https://gtacms.gtarcade.com/backend/editor/index?action=uploadimage';  // 上传图片到服务器
        // 3M
        editor.customConfig.uploadImgMaxSize = 3 * 1024 * 1024;
        // 限制一次最多上传 5 张图片
        editor.customConfig.uploadImgMaxLength = 1;
        // 自定义文件名
        editor.customConfig.uploadFileName = 'editor_img';
        // 将 timeout 时间改为 3s
        editor.customConfig.uploadImgTimeout = 5000;
    
        editor.customConfig.uploadImgHooks = {
            before: function (xhr, editor, files) {
                // 图片上传之前触发
                // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,files 是选择的图片文件
    
                // 如果返回的结果是 {prevent: true, msg: 'xxxx'} 则表示用户放弃上传
                // return {
                //     prevent: true,
                //     msg: '放弃上传'
                // }
                // alert("前奏");
            },
            success: function (xhr, editor, result) {
                // 图片上传并返回结果,图片插入成功之后触发
                // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果
                // var url = result.data.url;
                // alert(JSON.stringify(url));
                // editor.txt.append(url);
                // alert("成功");
            },
            fail: function (xhr, editor, result) {
                // 图片上传并返回结果,但图片插入错误时触发
                // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果
                alert("失败");
            },
            error: function (xhr, editor) {
                // 图片上传出错时触发
                // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象
                // alert("错误");
            },
            // 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置
            // (但是,服务器端返回的必须是一个 JSON 格式字符串!!!否则会报错)
            customInsert: function (insertImg, result, editor) {
                // 图片上传并返回结果,自定义插入图片的事件(而不是编辑器自动插入图片!!!)
                // insertImg 是插入图片的函数,editor 是编辑器对象,result 是服务器端返回的结果
                // 举例:假如上传图片成功后,服务器端返回的是 {url:'....'} 这种格式,即可这样插入图片:
                var url = result.data[0];
                insertImg(url);
                // result 必须是一个 JSON 格式字符串!!!否则报错
            }
        }
    

    好了,以上配置完毕就可以在前端进行使用了,咱们来看下效果:
    在这里插入图片描述

    完整代码

    import React, { Component } from 'react';
    import E from 'wangeditor'
    //import { inject, observer } from 'mobx-react'
    //import { withRouter } from 'react-router-dom'
    
    //@withRouter @inject('appStore') @observer
    class Editor extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                editorContent:''
             };
        }
    
        componentDidMount() {
            const elemMenu = this.refs.editorElemMenu;
            const elemBody = this.refs.editorElemBody;
            const editor = new E(elemMenu,elemBody)
            // 使用 onchange 函数监听内容的变化,并实时更新到 state 中
            editor.customConfig.onchange = html => {
                console.log(editor.txt.html())
                this.setState({
                    // editorContent: editor.txt.text()
                    editorContent: editor.txt.html()
                })
            }
            editor.customConfig.menus = [
                'head',  // 标题
                'bold',  // 粗体
                'fontSize',  // 字号
                'fontName',  // 字体
                'italic',  // 斜体
                'underline',  // 下划线
                'strikeThrough',  // 删除线
                'foreColor',  // 文字颜色
                'backColor',  // 背景颜色
                'link',  // 插入链接
                'list',  // 列表
                'justify',  // 对齐方式
                'quote',  // 引用
                'emoticon',  // 表情
                'image',  // 插入图片
                'table',  // 表格
                'video',  // 插入视频
                'code',  // 插入代码
                'undo',  // 撤销
                'redo'  // 重复
            ]
            editor.customConfig.uploadImgShowBase64 = true
            editor.create()
    
        };
    
        render() {
            return (
                <div className="shop">
                    <div className="text-area" >
                        <div ref="editorElemMenu"
                             style={{backgroundColor:'#f1f1f1',border:"1px solid #ccc"}}
                             className="editorElem-menu">
    
                        </div>
                        <div
                            style={{
                                padding:"0 10px",
                                overflowY:"scroll",
                                height:300,
                                border:"1px solid #ccc",
                                borderTop:"none"
                            }}
                            ref="editorElemBody" className="editorElem-body">
    
                        </div>
                    </div>
                </div>
            );
        }
    }
    
    export default Editor;
    
    

    写在最后

    以上就是如何在react项目中使用editor富文本编辑器的相关内容了。希望这篇文档能给您带来帮助,感谢阅读。

    展开全文
  • 最前面 为了 react 中更好的使用 ts,进行一下讨论 怎么合理的再 react 中使用 ts 的一些特性让... react 中使用 ts 的几点原则和变化 所有用到jsx语法的文件都需要以tsx后缀命名 使用组件声明时的Comp...

    写在最前面

    • 为了在 react 中更好的使用 ts,进行一下讨论
    • 怎么合理的再 react 中使用 ts 的一些特性让代码更加健壮

    讨论几个问题,react 组件的声明?react 高阶组件的声明和使用?class组件中 props 和 state 的使用?...

    在 react 中使用 ts 的几点原则和变化

    • 所有用到jsx语法的文件都需要以tsx后缀命名
    • 使用组件声明时的Component<P, S>泛型参数声明,来代替PropTypes!
    • 全局变量或者自定义的window对象属性,统一在项目根下的global.d.ts中进行声明定义
    • 对于项目中常用到的接口数据对象,在types/目录下定义好其结构化类型声明

    声明React组件

    • react中的组件从定义方式上来说,分为类组件和函数式组件。

    • 类组件的声明

    class App extends Component<IProps, IState> {
        static defaultProps = {
            // ...
        }
        
        readonly state = {
            // ...
        }; 
        // 小技巧:如果state很复杂不想一个个都初始化,可以结合类型断言初始化state为空对象或者只包含少数必须的值的对象:  readonly state = {} as IState;
    }
    复制代码

    需要特别强调的是,如果用到了state,除了在声明组件时通过泛型参数传递其state结构,还需要在初始化state时声明为 readonly

    这是因为我们使用 class properties 语法对state做初始化时,会覆盖掉Component<P, S>中对statereadonly标识。

    函数式组件的声明

    // SFC: stateless function components
    // v16.7起,由于hooks的加入,函数式组件也可以使用state,所以这个命名不准确。新的react声明文件里,也定义了React.FC类型^_^
    const List: React.SFC<IProps> = props => null
    复制代码

    class组件都要指明props和state类型吗?

    • 是的。只要在组件内部使用了propsstate,就需要在声明组件时指明其类型。
    • 但是,你可能发现了,只要我们初始化了state,貌似即使没有声明state的类型,也可以正常调用以及setState。没错,实际情况确实是这样的,但是这样子做其实是让组件丢失了对state的访问和类型检查!
    // bad one
    class App extends Component {
        state = {
            a: 1,
            b: 2
        }
     
        componentDidMount() {
            this.state.a // ok: 1
     
            // 假如通过setState设置并不存在的c,TS无法检查到。
            this.setState({
                c: 3
            });
            
            this.setState(true); // ???
        }
        // ...
    }
     
    // React Component
    class Component<P, S> {
            constructor(props: Readonly<P>);
            setState<K extends keyof S>(
                state: ((prevState: Readonly<S>, props: Readonly<P>) => (Pick<S, K> | S | null)) | (Pick<S, K> | S | null),
                callback?: () => void
            ): void;
            forceUpdate(callBack?: () => void): void;
            render(): ReactNode;
            readonly props: Readonly<{ children?: ReactNode }> & Readonly<P>;
            state: Readonly<S>;
            context: any;
            refs: {
                [key: string]: ReactInstance
            };
        }
     
     
    // interface IState{
    //    a: number,
    //    b: number
    // }
    
    // good one
    class App extends Component<{}, { a: number, b: number }> {
       
        readonly state = {
            a: 1,
            b: 2
        }
        
        //readonly state = {} as IState,断言全部为一个值
     
        componentDidMount() {
            this.state.a // ok: 1
     
            //正确的使用了 ts 泛型指示了 state 以后就会有正确的提示
            // error: '{ c: number }' is not assignable to parameter of type '{ a: number, b: number }'
            this.setState({
                c: 3
            });
        }
        // ...
    }
    复制代码

    使用react高阶组件

    什么是 react 高阶组件?装饰器?

    • 因为react中的高阶组件本质上是个高阶函数的调用,所以高阶组件的使用,我们既可以使用函数式方法调用,也可以使用装饰器。但是在TS中,编译器会对装饰器作用的值做签名一致性检查,而我们在高阶组件中一般都会返回新的组件,并且对被作用的组件的props进行修改(添加、删除)等。这些会导致签名一致性校验失败,TS会给出错误提示。这带来两个问题:

    第一,是否还能使用装饰器语法调用高阶组件?

    • 这个答案也得分情况:如果这个高阶组件正确声明了其函数签名,那么应该使用函数式调用,比如 withRouter
    import { RouteComponentProps } from 'react-router-dom';
     
    const App = withRouter(class extends Component<RouteComponentProps> {
        // ...
    });
     
    // 以下调用是ok的
    <App />
    复制代码

    如上的例子,我们在声明组件时,注解了组件的props是路由的RouteComponentProps结构类型,但是我们在调用App组件时,并不需要给其传递RouteComponentProps里说具有的locationhistory等值,这是因为withRouter这个函数自身对齐做了正确的类型声明。

    第二,使用装饰器语法或者没有函数类型签名的高阶组件怎么办?


    如何正确的声明高阶组件?

    • 就是将高阶组件注入的属性都声明可选(通过Partial这个映射类型),或者将其声明到额外的injected组件实例属性上。 我们先看一个常见的组件声明:
    import { RouteComponentProps } from 'react-router-dom';
     
    // 方法一
    @withRouter
    class App extends Component<Partial<RouteComponentProps>> {
        public componentDidMount() {
            // 这里就需要使用非空类型断言了
            this.props.history!.push('/');
        }
        // ...
    });
     
    // 方法二
    @withRouter
    class App extends Component<{}> {
        get injected() {
            return this.props as RouteComponentProps
        }
     
        public componentDidMount() {
            this.injected.history.push('/');
        }
        // ...
    复制代码

    如何正确的声明高阶组件?

    interface IUserCardProps {
        name: string;
        avatar: string;
        bio: string;
     
        isAdmin?: boolean;
    }
    class UserCard extends Component<IUserCardProps> { /* ... */}
    复制代码

    上面的组件要求了三个必传属性参数:name、avatar、bio,isAdmin是可选的。加入此时我们想要声明一个高阶组件,用来给UserCard传递一个额外的布尔值属性visible,我们也需要在UserCard中使用这个值,那么我们就需要在其props的类型里添加这个值:

    interface IUserCardProps {
        name: string;
        avatar: string;
        bio: string;
        visible: boolean;
     
        isAdmin?: boolean;
    }
    @withVisible
    class UserCard extends Component<IUserCardProps> {
        render() {
            // 因为我们用到visible了,所以必须在IUserCardProps里声明出该属性
            return <div className={this.props.visible ? '' : 'none'}>...</div>
        }
    }
     
    function withVisiable(WrappedComponent) {
        return class extends Component {
            render() {
                return <WrappedComponent {..this.props}  visiable={true} />
            }
        }
    }
    复制代码
    • 但是这样一来,我们在调用UserCard时就会出现问题,因为visible这个属性被标记为了必需,所以TS会给出错误。这个属性是由高阶组件注入的,所以我们肯定是不能要求都再传一下的。

    可能你此时想到了,把visible声明为可选。没错,这个确实就解决了调用组件时visible必传的问题。这确实是个解决问题的办法。但是就像上一个问题里提到的,这种应对办法应该是对付哪些没有类型声明或者声明不正确的高阶组件的。

    所以这个就要求我们能正确的声明高阶组件:

    interface IVisible {
        visible: boolean;
    }
     
     //排除 IVisible
    function withVisible<Self>(WrappedComponent: React.ComponentType<Self & IVisible>): React.ComponentType<Omit<Self, 'visible'>> {
        return class extends Component<Self> {
            render() {
                return <WrappedComponent {...this.props}  visible={true} />
            }
        }
    }
    复制代码

    如上,我们声明withVisible这个高阶组件时,利用泛型和类型推导,我们对高阶组件返回的新的组件以及接收的参数组件的props都做出类型声明。

    参考:

    • 组内大佬的wiki


    作者:leoeo
    链接:https://juejin.im/post/5bed5f03e51d453c9515e69b
    来源:掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    展开全文
  • 在React中使用Echart

    2018-05-06 17:20:45
    用Pro的意图本来是觊觎他的图表,以为可以省事不少,但实际开发发现文档偏少,再次开发起来也不太实用,目前来说图表这块还不算太成熟。然后还是选用了echart,在react中用起来有些不同之处莫过于对数据的操作...

    近期开发了一个react项目,用的是蚂蚁金服推出的脚手架——Ant Design/Ant Design Pro,基于dva框架进行开发。
    用Pro的意图本来是觊觎他的图表,以为可以省事不少,但在实际开发中发现文档偏少,再次开发起来也不太实用,目前来说图表这块还不算太成熟。然后还是选用了echart,在react中用起来有些不同之处莫过于对数据的操作。

    1.首先安装 react-echart 配置:

    $ npm install echarts --save-dev

    2.安装成功后可以直接引用,以下是为了避免图表配置导致文件过长,将图表配置的相关代码放入了 lineChart 文件中。

    module.exports = {
      	tooltip: {
      		trigger: 'axis'
      	},
      	legend: {
      		data:['本年级'],
      		x:'right'
      	},
      	grid: {
      		left: '3%',
      		right: '4%',
      		bottom: '3%',
      		containLabel: true
      	},
      	toolbox: {
      		feature: {
      			saveAsImage: {}
      		}
      	},
      	xAxis: {
      		type: 'category',
      		boundaryGap: false,
      		data: ['-', '-', '-', '-', '-', '-']
      	},
      	yAxis: {
            name : '单位(%)',
      		type: 'value'
      	},
      	series: [
      		{
      			name:'本年级',
      			type:'line',
      			stack: '总量',
      			color:'#1daef8',
      			data: [0, 0, 0, 0, 0, 0],
      		}
      	]
    };

    3.数据请求的时候有发现过组件内取不到 DOM 的情况,是因为组件未渲染,id还不存在,所以需要特殊处理。以下为主要代码:

    import React, { Component }from 'react';
    import {connect} from 'dva';
    import echarts from 'echarts/lib/echarts';
    import  'echarts/lib/chart/line';
    import lineChart from '../Chart/lineChart';
    //数据概况
    class DataProfile extends React.Component {
        constructor(props) {
            super(props)
            let id = ( '_' + Math.random()).replace('.','_');
            this.state = {
                pieId : 'pie' + id,	//定义初始化随机id
            }
        }
        initPie(id) {
    	//获取Chart的真实DOM,虽然react不推荐操作真实DOM,但是Echart对图表的渲染就是基于真实DOM的
            let myChart = echarts.getInstanceByDom(document.getElementById(id));
            if( myChart === undefined){
                myChart = echarts.init(document.getElementById(id));
            }
            myChart.setOption(config)
        }
        componentDidMount() {
    	this.initPie(this.state.pieId);
    	setTimeout(()=>{
    	        let chartRes = this.props.state.getCorrectRateLineChartData;	//取到返回的图表数据值
    		let chartDataX = [];		//创建X轴值数组
    		let chartDataY = [];		//创建Y轴值数组
    		if(chartRes && chartRes.data){
    			for(let i = 0; i < chartRes.data.length; i++){
    				if(chartRes.data[i].x){
    					let xVal = chartRes.data[i].x;
    					let xData = new Date(chartRes.data[i].x);
    					let time1 = (xData.getTime())/1000;
    					let y1Data = parseInt(chartRes.data[i].y1 * 100);
    					chartDataX[i] = chartRes.data[i].x;
    					chartDataY[i] = y1Data;
    				}
    			}
    		}
    		config.xAxis.data = chartDataX;		//更新图表的X轴默认值
    		config.series[0].data = chartDataY;		//更新图表的Y轴默认值
    		this.initPie(this.state.pieId);		//重新渲染图表
    		},1000)
        }
        render(){<div div={this.state.pieId} style={{width:500,height:400}}></div>} componentWillMount () { const {dispatch} = this.props; dispatch({ type: 'dataProfile/getCorrectRateLineChart' }); } export default connect((state) => ({ state: { ...state.dataProfile, loading: state.loading.models.dataProfile } }))(DataProfile);
     


    4.最终实现效果图。

    PC端实现效果图:

    手机端实现效果图:

    文中如有错误,敬请指出~
    5.参考文档链接
    https://www.jianshu.com/p/2e6789187d30

     

    展开全文
  • 在React中使用 Redux

    2018-09-14 14:10:26
    第一篇:使用webpack、babel、react、antdesign配置单页面应用开发环境 第二篇:使用react-router实现单页面应用路由 第三篇:优化单页面开发环境:webpack与react的运行时打包与热更新 第四篇...

    转载:https://www.jianshu.com/p/06f5285e2620

    这是Webpack+React系列配置过程记录的第六篇。其他内容请参考:

    这篇文章的主要内容包括:

    1. 修改一下之前存在的问题;
    2. 在框架中引入redux,使用一个例子简单介绍redux的使用方法;
    3. 其他redux辅助库。

    修复遗留问题

    1. webpack.prod.config.js中缺少了对path库的引用,执行构建npm run build:prod的时候失败。在文件开始的地方引入node.js的path库就可以了。
    2. package.json里面定义了一个build:dev的脚本,这个脚本其实有点多余,不过有时候需要打包测试版本的文件,所以还是需要存在。主要有个问题是webpack.dev.config.js中output节点下错误定义了path的值为根目录'/',这在使用npm start命令启动运行时打包的时候看不出问题,但是在使用npm run build:dev时会出现无法写文件到根目录的权限错误。只要把path的值改掉就可以。path: config.publicPath改成path: config.staticPath,publicPath: config.publicPath
    3. css-loader和less-loader导出的样式类名太长,还是把localIdentName中的path部分去掉比较好看。

    redux

    安装redux

    安装依赖的命令如下:

    npm install --save redux react-redux redux-thunk
    npm install --save-dev redux-logger
    

    redux不用说了,我是把它当成一个本地数据库使用,react-redux帮助你完成数据订阅,redux-thunk可以放你实现异步action,redux-logger是redux的日志中间件。

    关于redux与代码布局

    在开始介绍之前我想先就redux的使用发表一些自己的看法:

    前文说了我把redux当成一个本地数据库,因此我倾向于把redux封装类似于mvc中的Model的角色,独立为一层。这与另一种观点——我在公司的项目更倾向于把每个页面当成一个独立模块,每个模块维护自己的reducer和action的观点,有所出入。

    我的做法可以更好地实现reducer的复用。而对我自己来说更重要的好处是集中修改。更适合小项目或者独自开发一个项目的场景。

    我公司的项目的做法对多人协同开发更有利,毕竟每个人维护好自己的代码就可以了。公司项目的这种方法有几个问题让我比较难以接受:

    第一个是模块越多reducer和action的定义越多,很多时候这些代码都是差不多的。

    更重要的是第二个问题:模块数据在store里面的存储是直接在根state下面排列下来的,根state的数据格式样式有点像这样:

    {
        aModuleData:{...},
        bModuleData:{...},
        cModuleData:{...},
        dModuleData:{...},
        ...
    }
    

    项目的原意是希望每个模块的保持独立,但实际上使用的时候却是有极大的可能出现aModule同时使用aModuleData和bModuleData的情况。这跟每个人维护自己的代码的初衷有悖,也没有发挥好redux的真正能力。

    还有一个小问题是reducer的组织通常影响着应用数据state的样式,把reducer分散到每个模块之后,state的形式在代码上很难直管地反映出来,特别是当模块是动态加载的时候更甚。不过借助logger等工具可以解决。

    关于这块的争议Redux的教程中有提及。

    使用redux

    无论代码怎么布局,使用redux的方法主要还是三步曲:创建store、创建action、创建reducer。而在这之后才是与业务或者组件相关的数据处理和展示。

    先看一下我的做法的代码布局:

    代码布局

    1.创建store的代码集中在model/index.js中,model/actions/.js和model/reducer/.js里面分别是写action创建函数和reducer函数的地方,根据模块可以自己DIY。

    model/index.js的代码如下:

    model/index.js的代码

    2.  model/actions/index.js的代码如下:

    model/actions/index.js的代码

    3.  这里定义了一个名叫login的异步actionCreator以及三个普通的actionCreator。

     actionCreator被某个组件调用后会向store发送action,然后被reducer处理,                                                                                   reducer 定义在model/reducers/index.js中,代码如下:

    model/reducers/index.js的代码

    这就完成了三步曲了。上面的代码简单地模拟了登录的动作。登录页面用到的数据存放在loginPageData中,登陆后获取到的当前登录用户数据存储在实体数据entities中。

    接下来要把redux和react联系起来,也就是把redux的store中的数据交给react的组件使用。

    第一步需要挂载redux的store到react,为react提供数据支持。最简单的做法是找到应用的根组件(我这里是BasicExample.js),然后在它的render函数中最外层添加Providor标签。代码片段如下:

    挂载redux的store到react

    红线部分画出了改动点,从model/index.js中导出了store对象,通过react-redux提供的Providor标签挂载到react中,为react提供数据支持。

    看最后的红线中,我们在Home组件里面添加了这次的测试例子ReduxDemo。它的代码如下:

    ReduxDemo代码

    代码的重点在connect函数。这个函数也是由react-redux提供的。使用它可以包装普通的展示组件(这里是ReduxDemo——只负责展示数据),然后返回一个容器组件。connect函数通过第一个参数让展示组件订阅了来自store的数据;通过第二个参数让展示组件默认可以dispatch各种action。

    这个例子在ReduxDemo挂载完成后调用login接口模拟登陆。返回结果被塞到store中(数据格式由先前写好的reducers的组织方式决定)。页面根据store中的数据展示内容。由于login发出的远程请求是假的,所以这里总是失败,因此会显示失败的内容。

    关于redux的使用介绍到此结束。

    redux辅助库

    其实在上面的代码中我已经悄悄地提及了两个辅助库,也是我想在这里推荐的两个库:

    1. 开发工具redux-devtools:结合各种其他库可以实现可视化的调试界面。
    2. 数据规范化工具normalizr:规范化组织数据。经过三个项目的体验后,个人非常推荐使用这个库,可以让应用的数据组织更清晰、减少冗余数据、减少因数据刷新导致的性能影响。

    暂时不在这里展开介绍,有兴趣的可以到github上查一下文档。

    源码下载地址:https://pan.baidu.com/s/1dENYfuh



    作者:chardlau
    链接:https://www.jianshu.com/p/06f5285e2620 

    展开全文
  • react 中使用图片

    2018-10-11 16:16:39
    react中使用图片三种方式 1、分离引入方式 import React, { Component } from 'react' import Logo from '../assets/images/11.jpeg' class Image extends Component { constructor(props) { super(props); ...
  • (纯手打,如有错误的地方下方评论,3Q)什么是JSXJSX即...React在使用JSX的情况下一样可以工作,然而使用JSX可以提高组件的可读性,因此推荐使用JSX。这个是官网:http://facebook.github.io/jsx/举个栗子,...
  • 并不是所有的APP都需要使用全部的原生功能,包含支持全部特性的代码会增大应用的体积。但我们仍然希望能让你简单地根据自己的...我们随着React Native发布的所有库都仓库的Libraries文件夹下。其中有一些是纯Java
  • wangeditor react中使用

    2020-02-27 14:55:51
    一.基于javascript和css开发的 Web富文本编辑器, 轻量、简洁、易用、开源免费 使用原因 wangeditor的文档(地址:...使用wangeditor的项目,要对富文本的功能要求简单。 安装 npm 命令安装npm install wanged...
  • 前提准备 1.安装react-native-vector-...如果你想使用的默认字体文件,则需要链接资源库(可选) react-native link react-native-vector-icons 3.重新运行项目 4.测试运行一下代码任意组件 (这里使用...
  • 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本...本文主要介绍如何使用create-react-app创建的react项目中使用sass来编写样式文件。 本文github:https://github.com...
  • react中动态生成二维码(qrcode.react使用) 先进行包安装 npm install qrcode.react 使用它 import React from 'react' import QRCode from 'qrcode.react' React.render( <QRCode value=...
  • axios在react中用法

    2019-05-08 17:16:38
    链接:https://www.npmjs.com/package/axios
  • 最近项目开发的过程,遇到了要获取经纬度的问题,由于本人菜的一批,多方询问的情况下,得到了思否大佬@...最近参与的一个项目开发要求获取到一个仓库的经纬度,整个项目是使用React框架的,废话不多数,...
  • 你想像NodeJS中使用async/await 那样在React中同样使用它们? create-react-app 构建的项目支持开箱即用。 但是如果你想自己搭建的webpack配置的项目中使用,你可能会遇到 regeneratorRuntime is not defined 的...
  • 先去官网下载UEditor:... 文档结构图 注意:ueditor要放在public目录下面的static里面 接下来创建react的UEditor组件 ...import React, { Component } from 'react'; import './style.css...
  • <article data-v-4e83724e="" itemscope="itemscope" itemtype=... Facebook 于本月 12 号发布了 React Native v0.59,支持了hooks 的使用。让我们一起看下如何使用吧 什么是...
  • 04.在react中使用iconfont

    2019-05-30 08:41:00
    挑选你需要的图标放入购物车,然后 Iconfont 会为你打包你购物车里的图标,自动生成一种新的字体,可以选择下载到本地,你的项目引入这种字体,这样即便没有网络的情况也可以使用图标。 如何使用:阅读下面链接 ...
  • 最近react做一个项目,需要使用到地图展示地址,由于之前就有用过百度地图,申请过ak,所以这次就直接用百度地图了。但是之前是使用vue,react怎么使用百度地图还是第一次,特此记录,以备有需要的人。 本文...
1 2 3 4 5 ... 20
收藏数 34,240
精华内容 13,696