Setting State with Objects from Firebase










3















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:



enter image description here



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?










share|improve this question



















  • 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















3















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:



enter image description here



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?










share|improve this question



















  • 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













3












3








3








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:



enter image description here



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?










share|improve this question
















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:



enter image description here



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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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












  • 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












1 Answer
1






active

oldest

votes


















1














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;





share|improve this answer

























  • 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










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
);



);













draft saved

draft discarded


















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









1














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;





share|improve this answer

























  • 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















1














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;





share|improve this answer

























  • 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













1












1








1







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;





share|improve this answer















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;






share|improve this answer














share|improve this answer



share|improve this answer








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

















  • 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



















draft saved

draft discarded
















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Top Tejano songwriter Luis Silva dead of heart attack at 64

ReactJS Fetched API data displays live - need Data displayed static

Evgeni Malkin