react入门

导读:

   在未接触react,vue等组件化前端框架时,我所认知的前端均为许多不同的页面组成,不同的页面处理不同的业务逻辑,在一定角度上可以理解为页面的数量决定项目的大小。对前端的理解程度局限于页面不同元素的拼凑,样式的修改,js脚本实现参数传递,页面跳转,动态样式等等。

   初识react框架后,我对它的第一认知是:通过组件与组件之间的关联,组合形成一整套完善的业务逻辑。

学习流程:

1.环境搭建:

  •    安装node.js: 官网下载.msi安装包,默认安装即可。
  •    安装vscode:官网下载.exe执行文件,同样默认安装。
  •    新建html页面,页面引入相关js文件
1     <!--react核心库-->
2     <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
3     <!--提供与Dom相关的功能-->
4     <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
5     <!-- 升级es5->es6 支持jsx语法-->
6     <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>

2.JSX:

 jsx简单来说就是javascript上面的一种语法扩展,js-x见名知其意。

const component = <MyComponent />;
let test1 = <div><h1>hello world!</h1></div>;
// =>相当于lambda表达式中的 参数值->返回值
const ListItems = message.map(
    (item) =>
        <li>{item}</li>
);

3.组件:

 两种实现方式:

(1)定义 function函数,需注意函数需要接收props属性的对象,同时需要返回react元素。

function testFunc(props){
    return <p>hello {props.name}</p>
}

(2)定义一个class继承React.Component,需注意命名的组件以大写字母开头。

class MyComponent extends React.Component {
    render() {
        return <h1>hello {this.props.name} </h1>;
    }
}

4.复合组件:

 简单来说就是在一个父组件之间存在其他子组件,通过自顶向下的数据传输方式实现组件之间的耦合。

//实现组件之间的参数传递 ->接收组件 子组件
class RecieveComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            age: props.age,
            name: props.name
        }
    };

    render() {
        return (
            <div>
                <h5>姓名:{this.state.name}</h5>
                <h5>年龄:{this.state.age}</h5>
            </div>
        )
    }

}

//提供数据组件 ->父组件
class ProvideComponent extends React.Component {
    constructor() {
        super();
    }
    render() {
        return (
            <RecieveComponent age={22} name={"wsw"} />
        )
    }

}

5.props与state:

 props:属性,不可变,仅用于数据传输

  •     setProps(object newProps(,function callback)):
  •     replaceProps(object newProps(,function callback)):

 state:状态 ,可变,可用于触发ui更新

  •    setState(object newState(,function callback))
  •    replaceState(object newState(,function callback))
class LearnComponentApi extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            clickCount: 0
        }
        this.clickCountFunc = this.clickCountFunc.bind(this);
    }

    //设置每次点击改变clickCount属性的状态
    clickCountFunc() {
        //setState每次都会造成一次组件渲染,并不会立即执行,而是会生成一个state,由react进行批量state,DOM渲染
        this.setState(function (state) {
            return { clickCount: state.clickCount + 1 };
        });
    }
    
    render() {
        return (
            <button onClick={this.clickCountFunc}>当前点击次数为:{this.state.clickCount}</button>
        );
    }
}

6.条件渲染:

 1 //条件渲染,根据传入的属性改变页面的显示
 2 function Login(props) {
 3 
 4     function LoginIn(props) {
 5         return <h1>欢迎登陆!</h1>;
 6     }
 7 
 8     function UnLogin(props) {
 9         return <h1>登录失败!</h1>;
10     }
11 
12     const isLogin = props.isLogin;
13 
14     if (isLogin) {
15         return <LoginIn />;
16     }
17     return <UnLogin />;
18 }

7.事件:

ps:需要注意的是组件内自己定义的改变state的方法需要在初始化时进行绑定,否则使用该方法时会出现undefined未定义的问题

 1 //事件绑定 用户点击切换状态
 2 class MyEvent extends React.Component {
 3     constructor(props) {
 4         super(props);
 5         this.state = {
 6             isOn: true
 7         };
 8         this.handleClick = this.handleClick.bind(this);
 9     }
10 
11     handleClick() {
12         this.setState(preState => ({
13             isOn: !preState.isOn
14         }));
15     }
16 
17     render() {
18         return (
19             <button onClick={this.handleClick}>
20                 {this.state.isOn ? <h2></h2> : <h2></h2>}
21             </button>
22         )
23     }
24 }

handleClick() 等同于function handleClick(){}

{this.handleClick}等同于handleClick()

8.运算符:

//与运算符(true && expression ->expression /false && expression ->false) 三目运算符  condition ? true : false
function UseConditionComponent(props) {
    const unReadMessage = props.unReadMessage;
    //与运算符
    return (
        <div>
            {
                unReadMessage.length > 0 &&
                <h2>你有{unReadMessage.length}条消息未读!</h2>
            }
        </div>
    );

    //三目运算符
    return (
        unReadMessage.length > 0
            ? (<h2>你有{unReadMessage.length}条信息未读!</h2>)
            : (<h2>全部消息已读!</h2>)
    );
}

8.列表:

key:在react中用于获取每一个元素对象的状态,每一个元素对象都需要有自己的key且唯一

map()方法中的所返回的元素需要指定key

//列表  map  元素遍历
const message = ['react', 'vue', 'angular'];
// =>相当于lambda表达式中的 参数值->返回值
const ListItems = message.map(
    (item) =>
        <li>{item}</li>
);

//通过组件进行列表元素的封装遍历,需要在<li>标签中声明key,否则报key找不到错误
const hobby = ["唱", "跳", "rap"];
function ListComponent(props) {
    const elements = props.elements;
    //在map()方法中的元素需要指定key
    const listElements = elements.map(
        (ele) =>
            <li key={ele.toString()}>{ele}</li>
    )
    return <ul>{listElements}</ul>;
}

//列表li元素
function ListItem(props) {
    return <li>{props.value}</li>
}

//遍历ul元素
function ElementsForeach(props) {
    const members = props.members;
    return (
        <ul>
            {
                members.map(
                    (els) => <ListItem key={els.toString} value={els} />
                )
            }
        </ul>
    );
}

key在兄弟元素之间只能唯一,指定为确定的一个属性

//元素的key在它的兄弟元素之间唯一
function ForeachItems(props) {
    const pid = (
        <ul>
            {
                props.persons.map(
                    (s) => <li key={s.pid}>id:{s.pid}</li>
                )
            }
        </ul>
    );

    const pbody = props.persons.map(
        (e) =>
            <div key={e.pid}>
                <h5>姓名:{e.pname}</h5>
                <h5>年龄:{e.page}</h5>
            </div>
    );
    return (
        <div>
            <h4>key在兄弟元素中唯一</h4>
            {pid}
            {pbody}
        </div>
    );
}

const persons = [
    { pid: 1, pname: '张三', page: 18 },
    { pid: 2, pname: '李四', page: 20 }
];

9.表单(受控组件):input/textarea/select

//受控组件 表单操作 input,textarea,select
class FormComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            text: ""
        }
        this.submitValue = this.submitValue.bind(this);
        this.changeValue = this.changeValue.bind(this);
    }

    submitValue(event) {
        alert("提交的内容:" + this.state.text);
        event.preventDefault();
    }

    changeValue(e) {
        this.setState({
            //设置text的值为target的value ,且输入值只要为字母全转为大写
            text: e.target.value.toUpperCase()
        });
    }

    render() {
        return (
            <form onSubmit={this.submitValue}>
                <input type="text" value={this.state.text} onChange={this.changeValue} />
                <Textarea value={this.state.text} onChange={this.changeValue} />
                <select value={this.state.text} onChange={this.changeValue}>
                    <option value="唱"></option>
                    <option value="跳"></option>
                    <option value="rap">rap</option>
                </select>
                <input type="submit" value="提交" />
            </form>
        )
    }
}

 10.ReactDOM.render():

 将加载的内容转为html元素,并插入到指定的DOM节点

 <div id="test"></div>
ReactDOM.render(
    <div align='center'>
        <MyEvent />
        <MyComponent />
        <MyChangeState />
        <Login isLogin={true} />
        <UseConditionComponent unReadMessage={message} />
        <h5>通过单个组件遍历数组元素:</h5>
        <ListComponent elements={message} />
        <h5>通过复合组件遍历数组元素:</h5>
        <ElementsForeach members={hobby} />
        <ForeachItems persons={persons} />
        <LearnComponentApi />
        <FormComponent />
        <ProvideComponent />
        {test2}
    </div>
    ,
    document.getElementById('test')
);

11.React router(路由):

可以理解为一个url资源定位容器,通过路由配置可以实现如传统前端那样不同页面之间跳转的功能。

let Home = () => (
    <Bundle load={loadHome}>
        {Home => <Home/>}
    </Bundle>
);

let Detail = () => (
    <Bundle load={loadDetail}>
        {Detail => <Detail/>}
    </Bundle>
);

let Add = () => (
    <Bundle load={loadAdd}>
        {Add => <Add/>}
    </Bundle>
);
            <Router>
                <Switch>
                    <Route path="/" exact component={Home}/>
                    <Route path="/detail" component={Detail}/>
                    <Route path="/add" component={Add}/>
                    <Redirect to="/"/>
                </Switch>
            </Router>

 

 

 

 文章待完善。。。

posted @ 2019-10-28 18:11  无影云  阅读(187)  评论(0编辑  收藏  举报