Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xyzdata/733097991de729ab842d080f7724a571 to your computer and use it in GitHub Desktop.
Save xyzdata/733097991de729ab842d080f7724a571 to your computer and use it in GitHub Desktop.
redux state management react
@xyzdata
Copy link
Author

xyzdata commented Jul 10, 2017

https://ant.design/components/table-cn/#Column

// key	React 需要的 key,如果已经设置了唯一的 dataIndex,可以忽略这个属性

// dataIndex	列数据在数据项中对应的 key,支持 a.b.c 的嵌套写法
const columns = [
    {
        title: '产品名称 ',
        dataIndex: 'pname',
        key: 'productName'
    }, 
    {
        title: '产品ID',
        dataIndex: 'pid',
        key: 'productId',
        render: ((text) => (<a href="#">{text}</a>))
    }, 
    {
        title: '最新版本',
        dataIndex: 'lversion',
        key: 'latestVersion'
    },
    {
        title: '关联菜单',
        dataIndex: 'rmenu',
        key: 'relationMenu',
        render: ((text) => (<a href="#">{text}</a>))
    }
];

@xyzdata
Copy link
Author

xyzdata commented Jul 10, 2017

Ant Table 数据获取

https://www.bbsmax.com/A/gAJGGRXJZR/

http://010x.ant.design/components/table/#

开始使用table组件时,不知道如何获取这一行的数据!

  1. 第一种方法是配置 rowSelection,在 onSelect 函数被调用的时候,可以获取当前行以及其子行的数据。
  2. 第二种方法是配置 Column中的 render 属性,这个属性对应一个函数,fun(text, record, index){}, 这是个渲染函数,参数分别为当前行的值,当前行数据,行索引,return可以决定表格里最终存放的值。
    {
        title: '关联菜单',
        dataIndex: 'rmenu',
        key: 'relationMenu',
        render: (
            (text, record, index) => {
                console.log(record);
                return(
                    <a href="#" onClick={() => alert(record.pid)} >
                        {text} 
                        <span>&</span>
                        {record.pname + record.pid + record.lversion + record.rmenu}
                        <span>&</span>
                        {index}
                    </a>
                );
            }
        )
    }

@xyzdata
Copy link
Author

xyzdata commented Jul 10, 2017

@xyzdata
Copy link
Author

xyzdata commented Jul 10, 2017

Lifting State Up

在React中,共享状态是通过将其移动到需要它的组件的最接近的共同祖先来实现的。这被称为“提升状态”。

https://facebook.github.io/react/docs/lifting-state-up.html#lifting-state-up

@xyzdata
Copy link
Author

xyzdata commented Jul 10, 2017

Props are Read-Only

https://facebook.github.io/react/docs/components-and-props.html#props-are-read-only

In React, this is usually solved by making a component "controlled".

The Data Flows Down

https://facebook.github.io/react/docs/state-and-lifecycle.html#the-data-flows-down

Neither parent nor child components can know if a certain component is stateful or stateless,
and they shouldn't care whether it is defined as a function or a class.

父组件和子组件都不能知道某个组件是有状态还是无状态,
并且它们不应该关心它是否被定义为一个函数或一个类。

@xyzdata
Copy link
Author

xyzdata commented Jul 10, 2017

// props is an object!


// message.text => array of objects
class MessageList extends React.Component {
    getChildren = () => {
        //
    }
    render() {
        const children = this.props.messages.map(
            (message, index) => {
                return(
                    <Message
                        key={index}
                        text={message.text}
                        color={message.color}
                        xyzClick={this.props.xyzClick}
                    />
                );
            }
        );
        return(
            <div>
                children = {children}
                <hr />
                <div>
                    BAD: <br />
                    {/* this.props = {this.props} */}
                    this.props.children = {this.props.color}
                    {/* this.props.arr = {this.props.arr} */}
                    {/* this.props.obj = {this.props.obj} */}
                </div>
            </div>
        );
    }
}

// text={message.text} => message object
class Message extends React.Component {
    test(){
        console.log(this.props.key);
    }
    render() {
        return (
            <div>
                this.props.text = {this.props.text}
                <br />
                this.props.color = <span style={{backgroundColor: this.props.color}}>{this.props.color}</span>
                <br />
                this.props.key = {this.props.key}
                <br />
                <Button color={this.props.color} xyzClick={this.props.xyzClick}>Delete</Button>
            </div>
        );
    }
}

// props.children ??? 
class Button extends React.Component {
    render() {
        return (
            <button
                style={{background: this.props.color}} 
                onClick={(e) => this.props.xyzClick(e)} >
                {this.props.children}
            </button>
        );
    }
}




const text = [
    {
    text: "text 1",
    color: "red"
    },
    {
    text: "text 2",
    color: "blue"
    },
    {
    text: "text 3",
    color: "gery"
    },
    {
    text: "text 4",
    color: "green"
    },
    {
    text: "text 5",
    color: "#f0f"
    }
];
const color = "green";
const ArrayTest = [1, 2, 3];
const ObjectTest = {"key": "value"};

class App extends React.Component{
  XC = (e) => {
      let m = e.toString();
      console.log(e, m);
      return alert(`e.toString(); =\n`, m);
  };
  render(){
      return(
          <div>
               <MessageList
                   messages={text}
                   color={color}
                   arr={ArrayTest}
                   obj={ObjectTest}
                   xyzClick={this.XC}/>
          </div>
      );
    }
};



export default App;

ReactDOM.render(
    <App />,
    mountNode
);

https://jscomplete.com/repl

@xyzdata
Copy link
Author

xyzdata commented Jul 10, 2017

image
image

@xyzdata
Copy link
Author

xyzdata commented Jul 11, 2017

FormItem = Form.Item;

const FormItem = Form.Item;

https://react2.xgqfrms.xyz/docs/jsx-in-depth.html#命名组件namespaced-components

只需要把你的"子组件"创建为主组件的属性。

Class Properties & bind(this)

https://facebook.github.io/react/docs/react-without-es6.html

@xyzdata
Copy link
Author

xyzdata commented Jul 11, 2017

注释

https://react2.xgqfrms.xyz/docs/jsx-in-depth.html#注释

var content = (
  <Nav>
    {/* child comment, 用 {} 包围 */}
    <Person
      /* 多

         注释 */
      name={window.isLoggedIn ? window.name : ''} // 行尾注释
    />
  </Nav>
);

@xyzdata
Copy link
Author

xyzdata commented Jul 11, 2017

@xyzdata
Copy link
Author

xyzdata commented Jul 11, 2017

@xyzdata
Copy link
Author

xyzdata commented Jul 11, 2017

props & 传数据

https://github.com/dvajs/dva-knowledgemap#往下传数据

父组件通过 props 传递 state 到子组件

https://github.com/dvajs/dva-knowledgemap#往上传数据

子组件通过调用父组件的 props 传递来的方法来修改 state

https://github.com/dvajs/dva-knowledgemap#理解-css-modules

@xyzdata
Copy link
Author

xyzdata commented Jul 11, 2017

@xyzdata
Copy link
Author

xyzdata commented Jul 11, 2017

@xyzdata
Copy link
Author

xyzdata commented Jul 11, 2017

@xyzdata
Copy link
Author

xyzdata commented Jul 11, 2017

https://facebook.github.io/react/docs/composition-vs-inheritance.html

请记住,组件可以接受任意 props,包括原始值,React元素或函数。

Remember that components may accept arbitrary props, including primitive values, React elements, or functions.

import React, {Component} from 'react';

const FancyBorder = (props) => {
    return (
        <div className={'FancyBorder FancyBorder-' + props.color}>
            {props.children}
        </div>
    ); 
}


const Dialog = (props) => {
    return (
        <FancyBorder color="blue">
            <h1 className="Dialog-title">
                {props.title}
            </h1>
            <p className="Dialog-message">
                {props.message}
            </p>
            {props.children}
        </FancyBorder>
    );
}

class SignUpDialog extends React.Component {
    constructor(props) {
        super(props);
        this.handleChange = this.handleChange.bind(this);
        this.handleSignUp = this.handleSignUp.bind(this);
        this.state = {
            login: ''
        };
    }
    handleChange(e) {
        this.setState({
            login: e.target.value
        });
    }
    handleSignUp() {
        alert(`Welcome aboard, ${this.state.login}!`);
    }
    render(props) {
        const record = this.props.data;
        console.log(`this.props.data`, this.props.data);
        return (
            <div>
                <Dialog 
                    title="Mars Exploration Program"
                    message="How should we refer to you?"
                    >
                    <input 
                        value={this.state.login}
                        onChange={this.handleChange}
                    />
                    <button
                        onClick={this.handleSignUp}
                        >
                        Sign Me Up!
                    </button>
                </Dialog>
            </div>
        );
    }
}


export {SignUpDialog};
export default SignUpDialog;

ant form validate

https://github.com/react-component/form/blob/3b9959b57ab30b41d8890ff30c79a7e7c383cad3/examples/server-validate.js#L74-L79

https://ant.design/components/form-cn/#components-form-demo-validate-other

@xyzdata
Copy link
Author

xyzdata commented Jul 11, 2017

import React, {Component} from 'react';

import {Form, Icon, Input, Button} from 'antd';
import {DatePicker, TimePicker} from 'antd';
const {MonthPicker, RangePicker} = DatePicker;

// import moment from 'moment';

const FormItem = Form.Item;

const hasErrors = (fieldsError) => {
    // 测试数组中的某些元素是否通过由提供的函数实现的测试。
    return Object.keys(fieldsError).some(field => fieldsError[field]);
};

const today = new Date().toLocaleString();

class HLF extends Component {
    constructor(props) {
        super(props);
        // this.onChange = this.onChange.bind(this);
        // this.onStartChange = this.onStartChange.bind(this);
    }
    state = {
        startValue: today
    };
    onChange = (field, value) => {
        this.setState({
            [field]: value,
        });
    };
    onStartChange = (value) => {
        console.log('typeof DatePicker value = \n', typeof(value));
        console.log('DatePicker value = \n', value);
        // value = value._d;
        this.onChange('startValue', value);
        console.log('DatePicker new value = \n', value);
    };
    componentDidMount() {
        // To disabled submit button at the beginning.
        this.props.form.validateFields();
    }
    handleSubmit = (e) => {
        e.preventDefault();
        this.props.form.validateFields((err, values) => {
            if (!err) {
                console.log('Received values of form: ', values);
            }
        });
    };
    clickSearchHandler = (e) => {
        e.preventDefault();
        console.log('Received values of form: ', e);
        let event = e;
        alert(event);
    };
    render() {
        // 解构赋值
        // alert(this.props.form);
        console.log(`this.props.form`, this.props.form);
        const {getFieldDecorator, getFieldsError, getFieldError, isFieldTouched} = this.props.form;
        // Only show error after a field is touched.
        const userNameError = isFieldTouched('userName') && getFieldError('userName');
        const textError = isFieldTouched('text') && getFieldError('text');
        const userTypeError = isFieldTouched('text') && getFieldError('text');
        //
        const phoneTypeError = isFieldTouched('text') && getFieldError('text');
        const emailTypeError = isFieldTouched('email') && getFieldError('email');
        return (
            <Form layout="inline" onSubmit={this.handleSubmit}>
                <FormItem
                    validateStatus={userNameError ? 'error' : ''}
                    help={userNameError || ''}
                    label="登录名"
                    >
                    {
                        getFieldDecorator('userName', {
                            rules: [{ required: false, message: '登录名' }],
                        })
                        (
                        <Input prefix={<Icon type="user" style={{ fontSize: 13 }} />} placeholder="登录名" />
                        )
                    }
                </FormItem>
                <FormItem
                    validateStatus={textError ? 'error' : ''}
                    help={textError || ''}
                    label="用户ID"
                    style={{}}
                    >
                    {
                        getFieldDecorator('text', {
                            rules: [{ required: false, message: '用户ID' }],
                        })
                        (
                            <Input prefix={<Icon type="idcard" style={{ fontSize: 13 }} />} type="text" placeholder="用户ID" />
                        )
                    }
                </FormItem>
                <FormItem
                    validateStatus={userTypeError ? 'error' : ''}
                    help={userTypeError || ''}
                    label="用户类型"
                    >
                    {
                        getFieldDecorator('text', {
                            rules: [{ required: false, message: '用户类型!' }],
                        })
                        (
                        <Input prefix={<Icon type="contacts" style={{ fontSize: 13 }} />} placeholder="用户类型" />
                        )
                    }
                </FormItem>
                <FormItem
                    validateStatus={textError ? 'error' : ''}
                    help={textError || ''}
                    label="用户姓名"
                    style={{}}
                    >
                    {
                        getFieldDecorator('text', {
                            rules: [{ required: false, message: '用户姓名' }],
                        })
                        (
                            <Input prefix={<Icon type="user-add" style={{ fontSize: 13 }} />} type="text" placeholder="用户姓名" />
                        )
                    }
                </FormItem>
                <br/>
                <FormItem
                    validateStatus={phoneTypeError ? 'error' : ''}
                    help={phoneTypeError || ''}
                    label="手机号"
                    style={{}}
                    >
                    {
                        getFieldDecorator('number', {
                            rules: [{ required: false, message: '手机号' }],
                        })
                        (
                            <Input prefix={<Icon type="phone" style={{ fontSize: 13 }} />} type="number" placeholder="手机号" />
                        )
                    }
                </FormItem>
                <FormItem
                    validateStatus={emailTypeError ? 'error' : ''}
                    help={emailTypeError || ''}
                    label={<span className="left-spaces">邮箱</span>}
                    style={{}}
                    >
                    {
                        getFieldDecorator('email', {
                            rules: [{ required: false, message: '邮箱' }],
                        })
                        (
                            <Input prefix={<Icon type="mail" style={{ fontSize: 13 }} />} type="email" placeholder="邮箱" />
                        )
                    }
                </FormItem>
                <FormItem
                    validateStatus={textError ? 'error' : ''}
                    help={textError || ''}
                    label="激活状态"
                    style={{}}
                    >
                    {
                        getFieldDecorator('text', {
                            rules: [{ required: false, message: '激活状态' }],
                        })
                        (
                            <Input prefix={<Icon type="file-text" style={{ fontSize: 13 }} />} type="text" placeholder="激活状态" />
                        )
                    }
                </FormItem>
                <FormItem
                    validateStatus={textError ? 'error' : ''}
                    help={textError || ''}
                    label="有效日期"
                    style={{}}
                    >
                    {
                        getFieldDecorator('text', {
                            rules: [{ required: false, message: '有效日期' }],
                        })
                        (
                            <div>
                                <RangePicker
                                    showTime
                                    format="YYYY-MM-DD HH:mm:ss"
                                    onChange={(e) => this.onStartChange(e)}
                                    />
                            </div>
                        )
                    }
                </FormItem>
                <span className="search-spaces"/>
                <FormItem>
                    <Button
                        icon="search"
                        type="primary"
                        htmlType="submit"
                        id="user-check-search"
                        onClick={this.clickSearchHandler}
                        >
                        查询
                    </Button>
                </FormItem>
            </Form>
        );
    }
}

const WHLF = Form.create({})(HLF);

export {WHLF};

export default WHLF;

/*

用户ID
用户姓名
登录名
手机号
邮箱
激活状态
有效日期	
用户类型:	内部用户

*/

@xgqfrms-GitHub
Copy link

@xgqfrms-GitHub
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment