reactjs – react-propag通过ListView和Navigator传播道具中的变化

前端之家收集整理的这篇文章主要介绍了reactjs – react-propag通过ListView和Navigator传播道具中的变化前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有以下情况.我有一个父组件,其中包含一个项目列表,其中任何项目都可以在子组件中向下钻取和查看.从子组件中,您应该能够更改正在查看的项目中的值.

在React网络世界中,这将很容易解决,父级将列表存储为状态,并将项目和回调作为道具传递给子项.

使用React Native,似乎丢失了这种可能性,因为从子组件引起的更改在导航之前不会触发重新呈现.

我录制了一个视频,看起来像这样. https://gfycat.com/GreenAgitatedChanticleer

代码如下.

index.ios.js

var React = require('react-native');
var {
    AppRegistry,Navigator
} = React;

var List = require('./list');

var listviewtest = React.createClass({
    render: function() {
        return (
            <Navigator
                initialRoute={{ component: List }}
                renderScene={(route,navigator) => {
                    return <route.component navigator={navigator} {...route.passProps} />;
                }} />

        );
    }
});

AppRegistry.registerComponent('listviewtest',() => listviewtest);

list.js

var React = require('react-native');
var _ = require('lodash');
var {
    View,Text,TouchableHighlight,ListView
} = React;

var Detail = require('./detail');

var List = React.createClass({
    getInitialState() {
        var LANGUAGES = [
            { id: 1,name: 'JavaScript' },{ id: 2,name: 'Obj-C' },{ id: 3,name: 'C#' },{ id: 4,name: 'Swift' },{ id: 5,name: 'Haskell' }
        ];

        var ds = new ListView.DataSource({ rowHasChanged: (a,b) => a !== b })
        return {
            languages: LANGUAGES,ds: ds.cloneWithRows(LANGUAGES)
        };
    },goToLanguage(language) {
        this.props.navigator.push({
            component: Detail,passProps: {
                language: language,changeName: this.changeName
            }
        });
    },changeName(id,newName) {
        var clone = _.cloneDeep(this.state.languages);
        var index = _.findIndex(clone,l => l.id === id);
        clone[index].name = newName;

        this.setState({
            languages: clone,ds: this.state.ds.cloneWithRows(clone)
        });
    },renderRow(language) {
        return (
            <TouchableHighlight onPress={this.goToLanguage.bind(this,language)}>
                <View style={{ flex: 1,flexDirection: 'row',alignItems: 'center',paddingTop: 5,paddingBottom: 5,backgroundColor: '#fff',marginBottom: 1 }}>
                    <Text style={{ marginLeft: 5,marginRight: 5 }}>{language.name}</Text>
                </View>
            </TouchableHighlight>
        );
    },render() {
        return (
            <View style={{ flex: 1,backgroundColor: '#ddd' }}>
                <Text style={{ marginTop: 60,marginLeft: 5,marginRight: 5,marginBottom: 10 }}>Select a language</Text>
                <ListView
                    dataSource={this.state.ds}
                    renderRow={this.renderRow} />
            </View>
        );
    }
});

module.exports = List;

detail.js

var React = require('react-native');
var {
    View,TouchableHighlight
} = React;

var Detail = React.createClass({
    changeName() {
        this.props.changeName(this.props.language.id,'Language #' + Math.round(Math.random() * 1000).toString());
    },goBack() {
        this.props.navigator.pop();
    },backgroundColor: '#ddd',justifyContent: 'center' }}>
                <Text>{this.props.language.name}</Text>

                <TouchableHighlight onPress={this.changeName}>
                    <Text>Click to change name</Text>
                </TouchableHighlight>

                <TouchableHighlight onPress={this.goBack}>
                    <Text>Click to go back</Text>
                </TouchableHighlight>
            </View>
        );
    }
});

module.exports = Detail;
事实证明这种行为是故意的,至少现在是这样.这里有一个讨论主题https://github.com/facebook/react-native/issues/795

对于寻找解决方法的任何人,我使用RCTDeviceEventEmitter在Navigator中传递数据.更新了以下代码

list.js

var React = require('react-native');
var _ = require('lodash');
var {
    View,ListView
} = React;

var Detail = require('./detail');
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');

var List = React.createClass({
    getInitialState() {
        var LANGUAGES = [
            { id: 1,passProps: {
                initialLanguage: language,l => l.id === id);
        clone[index].name = newName;

        RCTDeviceEventEmitter.emit('languageNameChanged',clone[index]);

        this.setState({
            languages: clone,TouchableHighlight
} = React;

var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');

var Detail = React.createClass({
    getInitialState() {
        return {
            language: this.props.initialLanguage,subscribers: []
        };
    },componentDidMount() {
        var subscriber = RCTDeviceEventEmitter.addListener('languageNameChanged',language => {
            this.setState({ language });
        });

        this.setState({
            subscribers: this.state.subscribers.concat([subscriber])
        });
    },componentWillUnmount() {
        this.state.subscribers.forEach(sub => {
            console.log('removing');
            sub.remove();
        });
    },changeName() {
        this.props.changeName(this.state.language.id,justifyContent: 'center' }}>
                <Text>{this.state.language.name}</Text>

                <TouchableHighlight onPress={this.changeName}>
                    <Text>Click to change name</Text>
                </TouchableHighlight>

                <TouchableHighlight onPress={this.goBack}>
                    <Text>Click to go back</Text>
                </TouchableHighlight>
            </View>
        );
    }
});

module.exports = Detail;
原文链接:https://www.f2er.com/react/443140.html

猜你在找的React相关文章