如何获得React应用程序的状态?

时间:2016-01-05 19:44:57

标签: reactjs state

所以,我已经用一些状态构建了这个React应用程序。我想知道那个状态是什么,所以我可以把它保存到localStorage并让状态从一个会话转移到另一个会话。基本上,应用程序非常复杂,我不希望人们失去他们的“位置”只是因为关闭它并稍后再打开它。

通过阅读React文档,我没有看到任何引用从React的外部访问组件的状态。

这可能吗?

3 个答案:

答案 0 :(得分:1)

您永远不应该尝试从组件中获取状态,因为组件应始终表示并且不会自己生成状态。不要求组件的状态,而是要求状态本身。

话虽这么说,我肯定会看到你来自哪里。在谈到React时,术语"陈述"似乎确实很模糊。

  

我没有看到任何引用访问组件状态的内容   来自React之外。

一劳永逸,差异在于:

  • 当地的州,不应该坚持:this.statethis.setState等。 本地状态仅存在于组件内,并且一旦组件死亡将会死亡。
  • 全球状态,可以保留:this.props.passedState全局状态只传递给组件,它不能直接修改它。视图层将调整为它传递的任何全局状态。

或简单地说:

  • this.state表示当地的州,不会被保留。
  • this.props.state表示通过状态,可以保留,我们只是不知道并且我们不关心

实施例

以下示例使用了Babel的stage-1 Preset

React就是提供数据结构的显示表示。让我们假设我们有以下对象可见地表示:

let fixtures = {
   people: [
        {
            name: "Lukas"
        },
        {
            name: "fnsjdnfksjdb"
        }
    ]
}

我们有一个App组件,可为Person数组中的每个条目呈现people个组件。

import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';

class Person extends Component {

    static propTypes = {
        name: PropTypes.string.isRequired
    }

    render() {
        return (
            <li>
                <input type="text" value={this.props.name} />
            </li>
        );
    }
}

class App extends Component {

    static propTypes = {
        people: PropTypes.array.isRequired
    }

    render() {
        let people = this.people.map(person => {
            <Person name={person.name} />
        });
        return (
            <ul>
                {people}
            </ul>
        );
    } 
}

ReactDOM.render(
    <App people={fixtures} />, 
    document.getElementById('yourid')
);

现在,我们将实现焦点功能。有两个选项:

  1. 我们不关心用户上次使用该应用时关注的是哪个人,因此我们使用本地状态。
  2. 我们关心上次用户使用该应用时关注的是哪个人,因此我们使用全局状态。
  3. 选项1

    任务很简单。只需调整People组件,一旦焦点发生变化,它就会知道(并重新渲染)。原始数据结构不会被改变,组件是否聚焦的信息是 仅客户端信息将在客户端关闭/重置/无论何时丢失。 状态是本地的:我们使用component.setState将更改分派给本地状态

    class Person extends Component {
        static propTypes = {
            name: PropTypes.string.isRequired
        }
        constructor(...args) {
            super(...args);
            this.state = {
                isFocused: false
            }
            this.onFocus = this.onFocus.bind(this);
            this.onBlur = this.onBlur.bind(this);
        }
    
        static propTypes = {
            name: PropTypes.string.isRequired
        }
    
        onFocus() {
            this.setState({
                isFocused: true;
            });
        }
    
        onBlur() {
            this.setState({
                isFocused: false;
            });
        }
    
        render() {
            let borderColor = this.state.isFocused ? '#ff0' : '#000'; 
                style = {
                    border: `1px solid ${borderColor}`
                }
            return (
                <li>
                    <input 
                        style={style} 
                        type="text" 
                        value={this.props.name} 
                        onFocus={this.onFocus}
                        onBlur={this.onBlur}
                        />
                </li>
            );
        }
    }
    

    选项2

    我们实际上希望将焦点元素保留到我们拥有的任何商店(例如后端),因为我们关心最后的状态。 状态是全局的:React组件仅接收道具作为&#34; state&#34;,甚至是关于元素是否聚焦的粒度信息。保持并将全局状态提供给应用程序,它将相应地运行。

    function setFocus(index) {
        fixtures.people[index].isFocused = true;
        render();
    }
    
    function clearFocus(index) {
        fixtures.people[index].isFocused = false;
        render();
    }
    
    function render() {
        ReactDOM.render(
        <App people={fixtures} />, 
        document.getElementById('yourid')
        );
    } 
    
    
    class Person extends Component {
        static propTypes = {
            name: PropTypes.string.isRequired,
            isFocused: PropTypes.bool,
            index: PropTypes.number.isRequired
        }
    
        static defaultProps = {
            isFocused: false
        }
    
        constructor(...args) {
            super(...args);
            this.onFocus = this.onFocus.bind(this);
            this.onBlur = this.onBlur.bind(this);
        }
    
        static propTypes = {
            name: PropTypes.string.isRequired
        }
    
        onFocus() {
            setFocus(this.props.index);
        }
    
        onBlur() {
            clearFocus(this.props.index);
        }
    
        render() {
            let borderColor = this.props.isFocused ? '#ff0' : '#000'; 
                style = {
                    border: `1px solid ${borderColor}`
                }
            return (
                <li>
                    <input 
                        style={style} 
                        type="text" 
                        value={this.props.name} 
                        onFocus={this.onFocus}
                        onBlur={this.onBlur}
                        />
                </li>
            );
        }
    }
    
    class App extends Component {
    
        static propTypes = {
            people: PropTypes.array.isRequired
        }
    
        render() {
            let people = this.people.map((person, index) => {
                <Person name={person.name} index={index} isFocused={person.isFocused} />
            });
            return (
                <ul>
                    {people}
                </ul>
            );
        } 
    }
    render();
    

答案 1 :(得分:0)

我认为问题的解决方案实际上取决于您的应用程序是如何建模的。

理想情况下,您需要(取决于复杂性)将是单个(flux / redux)商店,您可以在其上订阅更改,如果它是差异,则将其保存到{{1} }。

然后,您需要确定将此数据引导到单个商店的方法。

他们没有API 本身(我知道)可以专门做你想要的。

答案 2 :(得分:0)

不要试图从React外部获取状态 - 将状态从React传递到任何需要的位置。

在你的情况下,我会做这个componentDidUpdate。

var SampleRootComponent = React.createClass({
    componentDidUpdate: function() {
        localStorage.setItem(JSON.stringify(this.state))
    }
})

你是对的,因为没有办法从外面获得国家;你必须从React设置它。但是没有理由认为这是一件坏事 - 如果你需要将信息传递给其他东西,只需从React内部调用一个外部函数,如图所示。没有功能丢失。