Setting State with Objects from Firebase
I'm having trouble setting the state of a component in React. The component is called "Search" and uses react-select. The full component is here:
class Search extends React.Component
constructor(props)
super(props);
let options = ;
for (var x in props.vals)
options.push( value: props.vals[x], label: props.vals[x], searchId: x );
;
this.state =
inputValue: '',
value: options
;
handleChange = (value: any, actionMeta: any) =>
if(actionMeta.action == "remove-value")
this.props.onRemoveSearch( searchId: actionMeta.removedValue.searchId )
this.setState( value );
;
handleInputChange = (inputValue: string) =>
this.setState( inputValue );
;
handleSearch = ( value, inputValue ) =>
this.setState(
inputValue: '',
value: [...value, createOption(inputValue)], // Eventually like to take this out...
);
this.props.onSearch( inputValue );
handleKeyDown = (event: SyntheticKeyboardEvent<HTMLElement>) =>
const inputValue, value = this.state;
if (!inputValue) return;
switch (event.key)
case 'Enter':
case 'Tab':
this.handleSearch(
value,
inputValue
);
event.preventDefault();
;
render()
const inputValue, value = this.state;
return (
<div className="search">
<div className="search__title">Search</div>
<Tooltip
content=this.props.tooltipContent
direction="up"
arrow=true
hoverDelay=400
distance=12
padding="5px"
>
<CreatableSelect
className="tags"
components=components
inputValue=inputValue
isMulti
menuIsOpen=false
onChange=this.handleChange
onInputChange=this.handleInputChange
onKeyDown=this.handleKeyDown
placeholder="Add filters here..."
value=value
/>
</Tooltip>
</div>
);
module.exports = Search;
You've probably noticed the strange thing that I'm doing in the constructor function. That's because I need to use data from my firebase database, which is in object form, but react-select expects an array of objects
with a "value" and "label" property. Here's what my data looks like:
To bridge the gap, I wrote a for-in loop which creates the array (called options) and passes that to state.value.
The problem: Because I'm using this "for in" loop, React doesn't recognize when the props have been changed. Thus, the react-select component doesn't re-render. How do I pass down these props (either modifying them inside the parent component or within the Search component) so that the Search component will re-render?
javascript arrays reactjs firebase firebase-realtime-database
add a comment |
I'm having trouble setting the state of a component in React. The component is called "Search" and uses react-select. The full component is here:
class Search extends React.Component
constructor(props)
super(props);
let options = ;
for (var x in props.vals)
options.push( value: props.vals[x], label: props.vals[x], searchId: x );
;
this.state =
inputValue: '',
value: options
;
handleChange = (value: any, actionMeta: any) =>
if(actionMeta.action == "remove-value")
this.props.onRemoveSearch( searchId: actionMeta.removedValue.searchId )
this.setState( value );
;
handleInputChange = (inputValue: string) =>
this.setState( inputValue );
;
handleSearch = ( value, inputValue ) =>
this.setState(
inputValue: '',
value: [...value, createOption(inputValue)], // Eventually like to take this out...
);
this.props.onSearch( inputValue );
handleKeyDown = (event: SyntheticKeyboardEvent<HTMLElement>) =>
const inputValue, value = this.state;
if (!inputValue) return;
switch (event.key)
case 'Enter':
case 'Tab':
this.handleSearch(
value,
inputValue
);
event.preventDefault();
;
render()
const inputValue, value = this.state;
return (
<div className="search">
<div className="search__title">Search</div>
<Tooltip
content=this.props.tooltipContent
direction="up"
arrow=true
hoverDelay=400
distance=12
padding="5px"
>
<CreatableSelect
className="tags"
components=components
inputValue=inputValue
isMulti
menuIsOpen=false
onChange=this.handleChange
onInputChange=this.handleInputChange
onKeyDown=this.handleKeyDown
placeholder="Add filters here..."
value=value
/>
</Tooltip>
</div>
);
module.exports = Search;
You've probably noticed the strange thing that I'm doing in the constructor function. That's because I need to use data from my firebase database, which is in object form, but react-select expects an array of objects
with a "value" and "label" property. Here's what my data looks like:
To bridge the gap, I wrote a for-in loop which creates the array (called options) and passes that to state.value.
The problem: Because I'm using this "for in" loop, React doesn't recognize when the props have been changed. Thus, the react-select component doesn't re-render. How do I pass down these props (either modifying them inside the parent component or within the Search component) so that the Search component will re-render?
javascript arrays reactjs firebase firebase-realtime-database
2
If your component is not unmounting, the constructor will not be rerun. So your for in loop will not be rerun unless it unmounts. Another option would be to move the options into your render method, or add an additional lifecycle method of componentDidUpdate
– Naismith
Nov 16 '18 at 3:12
add a comment |
I'm having trouble setting the state of a component in React. The component is called "Search" and uses react-select. The full component is here:
class Search extends React.Component
constructor(props)
super(props);
let options = ;
for (var x in props.vals)
options.push( value: props.vals[x], label: props.vals[x], searchId: x );
;
this.state =
inputValue: '',
value: options
;
handleChange = (value: any, actionMeta: any) =>
if(actionMeta.action == "remove-value")
this.props.onRemoveSearch( searchId: actionMeta.removedValue.searchId )
this.setState( value );
;
handleInputChange = (inputValue: string) =>
this.setState( inputValue );
;
handleSearch = ( value, inputValue ) =>
this.setState(
inputValue: '',
value: [...value, createOption(inputValue)], // Eventually like to take this out...
);
this.props.onSearch( inputValue );
handleKeyDown = (event: SyntheticKeyboardEvent<HTMLElement>) =>
const inputValue, value = this.state;
if (!inputValue) return;
switch (event.key)
case 'Enter':
case 'Tab':
this.handleSearch(
value,
inputValue
);
event.preventDefault();
;
render()
const inputValue, value = this.state;
return (
<div className="search">
<div className="search__title">Search</div>
<Tooltip
content=this.props.tooltipContent
direction="up"
arrow=true
hoverDelay=400
distance=12
padding="5px"
>
<CreatableSelect
className="tags"
components=components
inputValue=inputValue
isMulti
menuIsOpen=false
onChange=this.handleChange
onInputChange=this.handleInputChange
onKeyDown=this.handleKeyDown
placeholder="Add filters here..."
value=value
/>
</Tooltip>
</div>
);
module.exports = Search;
You've probably noticed the strange thing that I'm doing in the constructor function. That's because I need to use data from my firebase database, which is in object form, but react-select expects an array of objects
with a "value" and "label" property. Here's what my data looks like:
To bridge the gap, I wrote a for-in loop which creates the array (called options) and passes that to state.value.
The problem: Because I'm using this "for in" loop, React doesn't recognize when the props have been changed. Thus, the react-select component doesn't re-render. How do I pass down these props (either modifying them inside the parent component or within the Search component) so that the Search component will re-render?
javascript arrays reactjs firebase firebase-realtime-database
I'm having trouble setting the state of a component in React. The component is called "Search" and uses react-select. The full component is here:
class Search extends React.Component
constructor(props)
super(props);
let options = ;
for (var x in props.vals)
options.push( value: props.vals[x], label: props.vals[x], searchId: x );
;
this.state =
inputValue: '',
value: options
;
handleChange = (value: any, actionMeta: any) =>
if(actionMeta.action == "remove-value")
this.props.onRemoveSearch( searchId: actionMeta.removedValue.searchId )
this.setState( value );
;
handleInputChange = (inputValue: string) =>
this.setState( inputValue );
;
handleSearch = ( value, inputValue ) =>
this.setState(
inputValue: '',
value: [...value, createOption(inputValue)], // Eventually like to take this out...
);
this.props.onSearch( inputValue );
handleKeyDown = (event: SyntheticKeyboardEvent<HTMLElement>) =>
const inputValue, value = this.state;
if (!inputValue) return;
switch (event.key)
case 'Enter':
case 'Tab':
this.handleSearch(
value,
inputValue
);
event.preventDefault();
;
render()
const inputValue, value = this.state;
return (
<div className="search">
<div className="search__title">Search</div>
<Tooltip
content=this.props.tooltipContent
direction="up"
arrow=true
hoverDelay=400
distance=12
padding="5px"
>
<CreatableSelect
className="tags"
components=components
inputValue=inputValue
isMulti
menuIsOpen=false
onChange=this.handleChange
onInputChange=this.handleInputChange
onKeyDown=this.handleKeyDown
placeholder="Add filters here..."
value=value
/>
</Tooltip>
</div>
);
module.exports = Search;
You've probably noticed the strange thing that I'm doing in the constructor function. That's because I need to use data from my firebase database, which is in object form, but react-select expects an array of objects
with a "value" and "label" property. Here's what my data looks like:
To bridge the gap, I wrote a for-in loop which creates the array (called options) and passes that to state.value.
The problem: Because I'm using this "for in" loop, React doesn't recognize when the props have been changed. Thus, the react-select component doesn't re-render. How do I pass down these props (either modifying them inside the parent component or within the Search component) so that the Search component will re-render?
javascript arrays reactjs firebase firebase-realtime-database
javascript arrays reactjs firebase firebase-realtime-database
edited Nov 16 '18 at 14:49
Frank van Puffelen
242k29387414
242k29387414
asked Nov 16 '18 at 3:01
Harry CramerHarry Cramer
377317
377317
2
If your component is not unmounting, the constructor will not be rerun. So your for in loop will not be rerun unless it unmounts. Another option would be to move the options into your render method, or add an additional lifecycle method of componentDidUpdate
– Naismith
Nov 16 '18 at 3:12
add a comment |
2
If your component is not unmounting, the constructor will not be rerun. So your for in loop will not be rerun unless it unmounts. Another option would be to move the options into your render method, or add an additional lifecycle method of componentDidUpdate
– Naismith
Nov 16 '18 at 3:12
2
2
If your component is not unmounting, the constructor will not be rerun. So your for in loop will not be rerun unless it unmounts. Another option would be to move the options into your render method, or add an additional lifecycle method of componentDidUpdate
– Naismith
Nov 16 '18 at 3:12
If your component is not unmounting, the constructor will not be rerun. So your for in loop will not be rerun unless it unmounts. Another option would be to move the options into your render method, or add an additional lifecycle method of componentDidUpdate
– Naismith
Nov 16 '18 at 3:12
add a comment |
1 Answer
1
active
oldest
votes
I would suggest not using the value
state. What you do is simply copying props into your state. You can use props in render()
method directly.
I reckon you use the value
state because you need to update it based on user actions. In this case, you could lift this state up into the parent component.
class Parent extends React.Component
constructor()
this.state = value: //structure should be the same as props.vals in ur code ;
render()
return (
<Search vals=this.state.value/>
);
class Search extends React.Component
constructor(props)
super(props);
this.state =
inputValue: '',
;
render()
const inputValue = this.state;
const vals = this.props;
let options = ;
for (var x in vals)
options.push( value: vals[x], label: vals[x], searchId: x );
;
return (
<div className="search">
<div className="search__title">Search</div>
<Tooltip
content=this.props.tooltipContent
direction="up"
arrow=true
hoverDelay=400
distance=12
padding="5px"
>
<CreatableSelect
value=options
/>
</Tooltip>
</div>
);
module.exports = Search;
Yes, I am using the value state because the react-select component relies on it. Could you perhaps give a short example of what you mean by "lifting" the state up to my parent component? How could I accomplish that? Thank you.
– Harry Cramer
Nov 16 '18 at 19:11
Many things depend on the "value" state in my Search component so I'm a little unclear about how to lift it up.
– Harry Cramer
Nov 16 '18 at 19:17
Please see my updated answer for a brief demo. Without insights into ur code, I can't provide a working demo. You may also need to update your event handler functions.
– tingxuanz
Nov 20 '18 at 23:02
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53330809%2fsetting-state-with-objects-from-firebase%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I would suggest not using the value
state. What you do is simply copying props into your state. You can use props in render()
method directly.
I reckon you use the value
state because you need to update it based on user actions. In this case, you could lift this state up into the parent component.
class Parent extends React.Component
constructor()
this.state = value: //structure should be the same as props.vals in ur code ;
render()
return (
<Search vals=this.state.value/>
);
class Search extends React.Component
constructor(props)
super(props);
this.state =
inputValue: '',
;
render()
const inputValue = this.state;
const vals = this.props;
let options = ;
for (var x in vals)
options.push( value: vals[x], label: vals[x], searchId: x );
;
return (
<div className="search">
<div className="search__title">Search</div>
<Tooltip
content=this.props.tooltipContent
direction="up"
arrow=true
hoverDelay=400
distance=12
padding="5px"
>
<CreatableSelect
value=options
/>
</Tooltip>
</div>
);
module.exports = Search;
Yes, I am using the value state because the react-select component relies on it. Could you perhaps give a short example of what you mean by "lifting" the state up to my parent component? How could I accomplish that? Thank you.
– Harry Cramer
Nov 16 '18 at 19:11
Many things depend on the "value" state in my Search component so I'm a little unclear about how to lift it up.
– Harry Cramer
Nov 16 '18 at 19:17
Please see my updated answer for a brief demo. Without insights into ur code, I can't provide a working demo. You may also need to update your event handler functions.
– tingxuanz
Nov 20 '18 at 23:02
add a comment |
I would suggest not using the value
state. What you do is simply copying props into your state. You can use props in render()
method directly.
I reckon you use the value
state because you need to update it based on user actions. In this case, you could lift this state up into the parent component.
class Parent extends React.Component
constructor()
this.state = value: //structure should be the same as props.vals in ur code ;
render()
return (
<Search vals=this.state.value/>
);
class Search extends React.Component
constructor(props)
super(props);
this.state =
inputValue: '',
;
render()
const inputValue = this.state;
const vals = this.props;
let options = ;
for (var x in vals)
options.push( value: vals[x], label: vals[x], searchId: x );
;
return (
<div className="search">
<div className="search__title">Search</div>
<Tooltip
content=this.props.tooltipContent
direction="up"
arrow=true
hoverDelay=400
distance=12
padding="5px"
>
<CreatableSelect
value=options
/>
</Tooltip>
</div>
);
module.exports = Search;
Yes, I am using the value state because the react-select component relies on it. Could you perhaps give a short example of what you mean by "lifting" the state up to my parent component? How could I accomplish that? Thank you.
– Harry Cramer
Nov 16 '18 at 19:11
Many things depend on the "value" state in my Search component so I'm a little unclear about how to lift it up.
– Harry Cramer
Nov 16 '18 at 19:17
Please see my updated answer for a brief demo. Without insights into ur code, I can't provide a working demo. You may also need to update your event handler functions.
– tingxuanz
Nov 20 '18 at 23:02
add a comment |
I would suggest not using the value
state. What you do is simply copying props into your state. You can use props in render()
method directly.
I reckon you use the value
state because you need to update it based on user actions. In this case, you could lift this state up into the parent component.
class Parent extends React.Component
constructor()
this.state = value: //structure should be the same as props.vals in ur code ;
render()
return (
<Search vals=this.state.value/>
);
class Search extends React.Component
constructor(props)
super(props);
this.state =
inputValue: '',
;
render()
const inputValue = this.state;
const vals = this.props;
let options = ;
for (var x in vals)
options.push( value: vals[x], label: vals[x], searchId: x );
;
return (
<div className="search">
<div className="search__title">Search</div>
<Tooltip
content=this.props.tooltipContent
direction="up"
arrow=true
hoverDelay=400
distance=12
padding="5px"
>
<CreatableSelect
value=options
/>
</Tooltip>
</div>
);
module.exports = Search;
I would suggest not using the value
state. What you do is simply copying props into your state. You can use props in render()
method directly.
I reckon you use the value
state because you need to update it based on user actions. In this case, you could lift this state up into the parent component.
class Parent extends React.Component
constructor()
this.state = value: //structure should be the same as props.vals in ur code ;
render()
return (
<Search vals=this.state.value/>
);
class Search extends React.Component
constructor(props)
super(props);
this.state =
inputValue: '',
;
render()
const inputValue = this.state;
const vals = this.props;
let options = ;
for (var x in vals)
options.push( value: vals[x], label: vals[x], searchId: x );
;
return (
<div className="search">
<div className="search__title">Search</div>
<Tooltip
content=this.props.tooltipContent
direction="up"
arrow=true
hoverDelay=400
distance=12
padding="5px"
>
<CreatableSelect
value=options
/>
</Tooltip>
</div>
);
module.exports = Search;
edited Nov 20 '18 at 6:08
answered Nov 16 '18 at 3:53
tingxuanztingxuanz
465
465
Yes, I am using the value state because the react-select component relies on it. Could you perhaps give a short example of what you mean by "lifting" the state up to my parent component? How could I accomplish that? Thank you.
– Harry Cramer
Nov 16 '18 at 19:11
Many things depend on the "value" state in my Search component so I'm a little unclear about how to lift it up.
– Harry Cramer
Nov 16 '18 at 19:17
Please see my updated answer for a brief demo. Without insights into ur code, I can't provide a working demo. You may also need to update your event handler functions.
– tingxuanz
Nov 20 '18 at 23:02
add a comment |
Yes, I am using the value state because the react-select component relies on it. Could you perhaps give a short example of what you mean by "lifting" the state up to my parent component? How could I accomplish that? Thank you.
– Harry Cramer
Nov 16 '18 at 19:11
Many things depend on the "value" state in my Search component so I'm a little unclear about how to lift it up.
– Harry Cramer
Nov 16 '18 at 19:17
Please see my updated answer for a brief demo. Without insights into ur code, I can't provide a working demo. You may also need to update your event handler functions.
– tingxuanz
Nov 20 '18 at 23:02
Yes, I am using the value state because the react-select component relies on it. Could you perhaps give a short example of what you mean by "lifting" the state up to my parent component? How could I accomplish that? Thank you.
– Harry Cramer
Nov 16 '18 at 19:11
Yes, I am using the value state because the react-select component relies on it. Could you perhaps give a short example of what you mean by "lifting" the state up to my parent component? How could I accomplish that? Thank you.
– Harry Cramer
Nov 16 '18 at 19:11
Many things depend on the "value" state in my Search component so I'm a little unclear about how to lift it up.
– Harry Cramer
Nov 16 '18 at 19:17
Many things depend on the "value" state in my Search component so I'm a little unclear about how to lift it up.
– Harry Cramer
Nov 16 '18 at 19:17
Please see my updated answer for a brief demo. Without insights into ur code, I can't provide a working demo. You may also need to update your event handler functions.
– tingxuanz
Nov 20 '18 at 23:02
Please see my updated answer for a brief demo. Without insights into ur code, I can't provide a working demo. You may also need to update your event handler functions.
– tingxuanz
Nov 20 '18 at 23:02
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53330809%2fsetting-state-with-objects-from-firebase%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
If your component is not unmounting, the constructor will not be rerun. So your for in loop will not be rerun unless it unmounts. Another option would be to move the options into your render method, or add an additional lifecycle method of componentDidUpdate
– Naismith
Nov 16 '18 at 3:12