javascript - React Native setting keys on elements -
i'm trying asyncstorage working in react-native, save user inputted data. although i've found through online resources , community, stuff driving me crazy.
even react docs seem flawed. code below taken straight asyncstorage page of react docs , pasted new, clean application (i've added final line of code register app, won't work without it).
the big block of code below posted reference. believe important bit line:
{this.state.messages.map(function(m) { return <text key={m}>{m}</text>; })}
i unique key errors, although have key set.
'use strict'; var react = require('react'); var reactnative = require('react-native'); var { appregistry, asyncstorage, pickerios, text, view } = reactnative; var pickeritemios = pickerios.item; var storage_key = '@asyncstorageexample:key'; var colors = ['red', 'orange', 'yellow', 'green', 'blue']; var basicstorageexample = react.createclass({ componentdidmount() { this._loadinitialstate().done(); }, async _loadinitialstate() { try { var value = await asyncstorage.getitem(storage_key); if (value !== null){ this.setstate({selectedvalue: value}); this._appendmessage('recovered selection disk: ' + value); } else { this._appendmessage('initialized no selection on disk.'); } } catch (error) { this._appendmessage('asyncstorage error: ' + error.message); } }, getinitialstate() { return { selectedvalue: colors[0], messages: [], }; }, render() { var color = this.state.selectedvalue; return ( <view> <pickerios selectedvalue={color} onvaluechange={this._onvaluechange}> {colors.map((value) => ( <pickeritemios key={value} value={value} label={value} /> ))} </pickerios> <text> {'selected: '} <text style={{color}}> {this.state.selectedvalue} </text> </text> <text>{' '}</text> <text onpress={this._removestorage}> press here remove storage. </text> <text>{' '}</text> <text>messages:</text> {this.state.messages.map(function(m) { return <text key={m}>{m}</text>; })} </view> ); }, async _onvaluechange(selectedvalue) { this.setstate({selectedvalue}); try { await asyncstorage.setitem(storage_key, selectedvalue); this._appendmessage('saved selection disk: ' + selectedvalue); } catch (error) { this._appendmessage('asyncstorage error: ' + error.message); } }, async _removestorage() { try { await asyncstorage.removeitem(storage_key); this._appendmessage('selection removed disk.'); } catch (error) { this._appendmessage('asyncstorage error: ' + error.message); } }, _appendmessage(message) { this.setstate({messages: this.state.messages.concat(message)}); }, }); exports.title = 'asyncstorage'; exports.description = 'asynchronous local disk storage.'; exports.examples = [ { title: 'basics - getitem, setitem, removeitem', render(): reactelement { return <basicstorageexample />; } }, ]; appregistry.registercomponent('basicstorageexample', () => basicstorageexample);
the above code works until select element have selected before. you're riddled console errors unique child keys. haven't been able figure out how avoid this.
console errors read:
index.ios.bundle:24458warning: flattenchildren(...): encountered 2 children same key, '6:$saved selection disk: orange'. child keys must unique; when 2 children share key, first child used.
if use message text key, , have 2 messages same text, key not unique. should use array index key:
{this.state.messages.map((message, i) => ( <text key={i}> {message} </text> )}
as side note, should make following changes code:
- use new react es6 syntax instead of old
react.createclass
- use es6
import
instead ofrequire()
'use strict'
redundant in es6 because it's strict default- this more opinionated should use eslint airbnb js style guide. integrates smoothly atom using atomlinter.
- but kudos on async/await! :)