文档章节

React: First Steps

Kolosek
 Kolosek
发布于 2018/04/02 16:44
字数 1450
阅读 2
React">收藏 0

ReactJS is a javascript library for building UIs. Although it's nowhere strictly defined, the idea with React is to follow the component-based ideology. Its declarative views make the code more predictable and easier to debug.

We use ReactJS combined with Webpack as a bundle manager, Redux combined with ImmutableJS for app state management, and some other libraries that make the developers life easier, like Gulp for handling build and deployment (and some other) tasks.

It can be used both as a simple static webpage, or it can be rendered on the server, for example, NodeJS. React applications rendered on servers are commonly called universal apps but are also sometimes referred as isomorphic.

In this article, we'll focus on React solely, as Redux and ImmutableJS will be documented separately.

React and JSX

In React you'll widely see parts of code like these:

    const element = <h1>Hello, world!</h1>;

This is neither a javascript string or HTML, but it's called JSX, a syntax extension for javascript. It's widely used inside render methods for React, to render dynamic parts of web pages. JSX produces React "elements" and is, for example, widely used when rendering something based on the condition.

To use JSX inside render method, it needs to be wrapped inside {} :

    <img src={user.avatarUrl}></img>

It's safe to use JSX, as it prevents injection attacks, so there's no worry there'll be some code injection.

You'll also definitely want to render a list of items or loop through some object at a certain point when developing. This is also done using JSX, and like for conditions, we have a separate article that focuses on rendering lists solely.
ALWAYS REMEMBER TO USE THE KEYS FOR LISTS!

The keys help React identify which items have changed, are added, or are removed. The keys must be unique and shouldn't be changeable for proper rendering of React elements in the list.

Component-based Organization and Props

React recommends component-based organization of the code. All logically separable parts of the code, like input field, a button, a form, a list etc. should be written in separate components.

All the simple parts of the code should be written as dummy components (often also called pure), meaning that they will only render based on parameters passed to them, and won't have an idea on any app logic.

Here are two examples of a dummy component:

    function Button({ onClick, text }) {
        return (
            <button
                onClick={onClick}
            >
                {text}
            </button>
        );
    }

You can pass the whole object as props using {...objectName} syntax; this will pass every key-value from objectName as separate prop.

    function InputField(props) {
        // props is an object containing keys like onChange, placeholder, etc...
        // 
        return (
            <input
                {...props}
            />
        );
    }

If you want to extract only some of the props, you can do it like this:

    function InputField(props) {
        const {
            onChange,
            placeholder,
            value,
        } = props;
        return (
            <input
                onChange={onChange}
                placeholder={placeholder}
                value={value}
            />
        );
    }

Now, how can these dummy components be used? Basically, you can use them by importing them into the file (using a relative path to the file) and then calling them in the render method. Here's an example:

    import React, { Component } from 'react';
    import InputField from '../components/InputField.js';
    import Button from '../components/Button.js';
    class Login extends Component {
        ...
        render() {
            return (
                <InputField
                    onChange={this.handleChange('email')}
                    placeholder={"Email"}
                    type="text"
                    value={this.state.email}
                />
                <InputField
                    onChange={this.handleChange('password')}
                    placeholder={"Password"}
                    type="password"
                    value={this.state.password}
                />
                <Button
                    onClick={this.login}
                >
                    {'Login'}
                </Button>
            );
        }
        ...
    }

Did you notice that I wrote this component the other way than earlier ones? That's because it's not a dummy one but will contain some more logic in it. Components written this way are called smart components or classes and can have other methods bound to it besides render method. You can find out more about dummy and smart components here.

Now, what exactly are props?

You can think of a component as a function (remember the dummy examples? They even use the standard function definition!). Basically, props are the parameters passed to that function when it's called. Anything can be a prop: a string, boolean, number, some other React element, undefined...

The most important thing to keep in mind about the props is that they are read-only, meaning that they can't be changed in the component receiving them and shouldn't be mutated. You can read more on how to pass props in our series on how to properly use props in React.

React State

In the previous chapter we've learned that props are parameters passed to the component. State, on the other hand, is private and its main purpose is to manipulate it within the component. The state is available only to classes, and is used to handle some internal changes (like updating some text stored based on onChange event):

    import React, { Component } from 'react';
    import InputField from '../components/InputField.js';
    ...
    class Login extends Component {
        // We define initial component state in constructor function
        constructor() {
            super();
            this.state = {
                email: '',
            }
        }
        // Handling state change is done by using this.setState function
        handleChange = (event) => {
            this.setState(() => {
                return {
                    email: event.target.value,
                };
            });
        }
        
        ...
        render() {
            return (
                <InputField
                    onChange={this.handleChange}
                    placeholder={"Email"}
                    type="text"
                    value={this.state.email}
                />
                {
                    ...
                }
            );
        }
        ...
    }

The state is initialized in the constructor, a special method called before initial component render. All the custom methods (like handleChange in the previous example) should be written using arrow function, so they're automatically bound to a component.

You might notice that some other people use this.setState like this:

    this.setState({
        email: event.target.value,
    });

This is a bad way to update the state! The state is updated asynchronously, and if there's need to update the state multiple times in a row, it'll just batch all the setStates done this way. Use functional way to update the state instead, as described in other examples.

Now, let's look at another example:

    import React, { Component } from 'react';
    import InputField from '../components/InputField.js';
    ...
    class Login extends Component {
        constructor() {
            super();
            this.state = {
                email: '',
                password: '',
            }
        }
        
        handleChange = (type) => (event) => {
            this.setState(() => {
                const stateUpdates = {};
                stateUpdates[type] = event.target.value;
                return stateUpdates;
            });
        }
        
        ...
        render() {
            return (
                <InputField
                    onChange={this.handleChange("email")}
                    placeholder={"Email"}
                    type="text"
                    value={this.state.email}
                />
                <InputField
                    onChange={this.handleChange("password")}
                    placeholder={"Password"}
                    type="password"
                    value={this.state.password}
                />
                {
                    ...
                }
            );
        }
        ...
    }

There's one rule when defining custom methods: never bind it in a render method. Above example shows a way how to do it correctly. If the method is bound in the render method, the new function will be created each time the component is rerendered. We have actually covered this in React Guide Props - Part I.

Component Lifecycle

Methods handling the component lifecycle are inherited from Component (yes, that Component you're importing at the top of the file). The most detailed description of lifecycle methods can be found here.

An important thing to remember is that in the case of universal apps (apps rendered on the server) browser related global variables like a window, localStorage, etc. can only be used after the component was mounted (i.e. they'll only be available in componentDidMount).

Styling React Components

Although React itself doesn't support directly using CSS for styling but is more oriented to inline jsx styles (passing style object prop to an HTML tag), this approach is not used that often.

Many, if not all, of the real-life projects you'll ever see, some CSS/SCSS loader is set up, so you can use styling like CSS columns with ease. This is configured via Webpack.

Routing in React

For routing, we use React Router v4. Its documentation is pretty straightforward and is pretty short, so it's a must-read. Basically, we use Router and Routes to define routes, Link component for linking pages and Redirect component to redirect to some other page on a certain action.

MATERIALS

Practice ideas:

  • Initiate a new react app using Create React App.
  • Try creating few very simple components: wrapper around input tag with a label, a button that'll be gray and have its text changed once disabled, an avatar.
  • Try creating a bit more complex component: a form that will have email, password, first and last name fields and a button (reuse dummy components you wrote in the previous step!)
  • Validate the form: email, password, first and last name fields should be filled in before button becomes enabled. Email should also be of a valid format.
  • Once the form is valid and login button is pressed, pop up an alert with values user filled in.
  • Congratulations! You've written your first ever React component! Next, you'll learn to use React with Redux.

This article is originally published on Kolosek Blog.

© 著作权归作者所有

Kolosek
粉丝 0
博文 29
码字总数 20461
作品 0
塞尔维亚
CEO
私信 提问
React 世界的一等公民 - 组件

Choerodon猪齿鱼平台使用 React 作为前端应用框架,对前端的展示做了一定的封装和处理,并配套提供了前端组件库Choerodon UI。结合实际业务情况,不断对组件优化设计,提高代码质量。 本文将...

Choerodon
02/19
1K
3
React 组件库 uiw 1.5.1 发布,新增 2 个组件

uiw 1.5.1 新版发布, 高品质的UI工具包,React的组件库,为打造高品质的React UI工具包的理想而奋斗!!! 更新内容 新特性: 新增InputPassword组件,用于显示和隐藏密码。 @Xing-Hee66ed8...

同一种调调
2017/12/07
1K
5
Ant Design 3.19.2 发布,企业级 UI 设计语言

Ant Design 3.19.2 发布了,更新内容如下: 修复 Tabs 在垂直卡片模式下标签不能滚动的问题。#16825 修复 Transfer 组件在 unmount 时 警告。#16822 @shiningjason 使用 Less 变量 、 代替 ...

xplanet
06/03
1K
0
Ant Design 3.22.1 发布,支持通过图片搜索图标

Ant Design 3.22.1 发布了,更新内容如下: 官网现在支持通过图片搜索图标啦!#18425 调整 Table 展开按钮的样式。c5344bd 修复 Table 的 属性被应用了两次的问题。#18330 @MrHeer 修复 Inpu...

xplanet
08/27
2.3K
5
React Native 0.57.4 发布,使用 React 编写原生应用的框架

React Native 0.57.4 已发布! 要注意的是,当升级到这个版本时,至少需要将 react 和 react-test-renderer 升级到 "16.6.0-alpha.8af6728",这是为即将到来的 React 16.6.0 的 "first class......

局长
2018/10/26
1K
2

没有更多内容

加载失败,请刷新页面

加载更多

debian10使用putty配置交换机console口

前言:Linux的推广普及,需要配合解决实际应用方能有成效! 最近强迫自己用linux进行实际工作,过程很痛苦,还好通过网络一一解决,感谢各位无私网友博客的帮助! 系统:debian10 桌面:xfc...

W_Lu
37分钟前
10
0
aelf Enterprise 0.8.0 beta有奖公测,“Bug奖金计划”重磅开启

2019年9月30日,aelf Enterprise 0.8.0 beta版正式发布。aelf Enterprise 0.8.0 beta是一个完备的区块链系统, 包含完备的区块链系统、开发套件、开发文档、以及配套的基础应用和基础服务。 ...

AELF开发者社区
38分钟前
8
0
oracle 初始化数据库脚本

create user lpf identified by 123456; create tablespace lpf_ts_cms datafile '/opt/app/oracle/product/11.2.0/lpf.dbf' size 200M; alter user lpf default tablespace lpf_ts_cms; sel......

internetafei
43分钟前
7
0
《区块链DAPP开发入门、代码实现、场景应用》笔记1——天外飞仙DAPP

Solidity编程语言解决了编写智能合约的不友好的问题,但是当合约编译并部署之后,对与这些接口的访问,对于一般的使用者来说,门槛有点高, 对普通用户来说也是非常不友好,为了使广大用户理...

柯南和由美
47分钟前
6
0
流程图制作软件推荐_流程图制作软件哪个好

流程图(Flow Chart)是一种表示算法思路的图示,通过特定图形、图表可以直观的说明某一过程。这种过程既可以是生产线上的工艺流程图,也可以标明某项任务必需的管理过程。为了便于识别,绘制...

工具分享
49分钟前
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部