Please take a look at my code for Dropdown,
I'm using the semantic ui react dropdown on an EditProfile component. I have pasted a sample code here, https://codesandbox.io/s/m4288nx4z8, but I could not get it to work because I'm not very familiar with functional components in React, I've always used Class component. But you can check the full code for the whole component below in the github gist.
https://gist.github.com/mayordwells/b0cbb7b63af85269091f1f98296fd9bb
Please, I need help on inserting values from multiple select options of a Dropdown into the Database and also a way to display that back upon viewing the profile edit page again.
I'm using semantic-ui-react in react + rails app.
Also when I insert a value using a normal drop down without multiple select, the value gets persisted into the database.
<Dropdown
placeholder='Select Country'
fluid
search
selection
options={countryOptions}
name='country'
defaultValue={this.state.extraInfo.country}
onChange={(e) => this.handleExtraInfoChange('country', e)}
/>
This code handles change for the dropdown elements.
handleExtraInfoChange = (name, event) => {
let value;
if (event.target.value !== undefined) {
value = event.target.value;
} else {
value = event.target.textContent;
}
let newExtraInfo = Object.assign(this.state.extraInfo, { [name]: value })
this.setState({ extraInfo: newExtraInfo});
}
But when I visit the page again, I get a white blank in the input box. Here's a screen pic for that. When I comment out the defaultValue or value property(i have tried with defaultValue and value), the white blank disappears, but the value picked by a user is also not seen.
Please advice what is a possible solution to this misbehavior? And what is the best way to insert multiple values into the Database?
Thanks in advance for your time.
A functional component does not have state, it's used for composition; you want to store state, so you either have to create a Component class or you need an external state container like redux.
Related
I've seen this problem about all around the web but nothing could come short of giving me a valid explanation.
I'm using Material-UI Select and the good ol' setState(...) from React (not hooks though)
My component is composed essentially of those lines :
class MyComponent extends Component {
exportOptions = ['CSV','SDF']
constructor(props) {
super(props);
this.state = {
[...]
formatToExportTo : this.exportOptions[0]
};
[...]
<Select value={this.state.formatToExportTo}
style={{width : "10em"}}
onChange={event=> {
this.setState({formatToExportTo : event.target.value})
}}>{
this.exportOptions.map(f=><MenuItem key={f} value={f}>{f}</MenuItem>)
}</Select>,
And my problem is that my Select component dosen't update its value after selecting another option.
So far I've tried :
setState({...this.state, formatToExport : event.target.value}) in the onChange= of the Select and in the Select tag : value = {this.state.formatToExport}
setState({...this.state, formatToExport : event.target.value}) in the onClick= of each options and in the Select tag : value = {this.state.formatToExport}. But that was only to see the update, because the event.target.value isn't right anyway
and the current version of my lines written above also onClick OR onChange (without tthe cloning of state which is supposed to be done by setState alone).
It's like in the official example so I truly don't see where this lack of update could come from. No matter what I try, the currently displayed value of the Select component doesn't change is display, even though the state was properly updated
Thank you for the time you took to read me !
After searching for 3 hours total :
normally value={this.state.formatToExportTo} should work ( I tried it alone without the rest of my app surrounding it)
But since I made some quircky things with my this and the order of update, I just had to replace :
value={this.state.formatToExportTo} by defaultValue={this.state.formatToExportTo}
That's all ! I hope it helps someone who'll come by this question
By default the ChipField can only show the content of a field, at least this is what the documentation tells. The example below displays the contents of the field name.
<ReferenceArrayField source="substances" reference="substances" label="Substanzen">
<SingleFieldList>
<ChipField source="name" />
</SingleFieldList>
</ReferenceArrayField>
However, I want ChipField to display a text combined of information from several fields:
const Substanz = ({ record }) => {
return record.name+" ("+record.unit+")";
};
<ReferenceArrayField source="substances" reference="substances" label="Substanzen">
<SingleFieldList>
<ChipField source={<Substanz />} /> <---- this does not work!
</SingleFieldList>
</ReferenceArrayField>
but unfortunately, source only accepts a field name, not an object like the OptionText prop of the SelectInput field.
What is the expected way to do this?
I think you are almost there with your custom SubstanzField component. Just use MUI styled component to make your own ChipField-like looking component and pass it directly inside of the SingleFieldList
MUI Chips docs
Don't know if you expected more sophisticated solution but this should be simple and flexible enough for your case.
In my render method i render some cards that all have button and when i click on the button i want to disabled them.
Those buttons are checking if the value of the array is true and if it is it's disabling the button but this is only working when i refresh the page and i want the button to be disabled directly on click
Here is my try
//this is checking from my database if it include the id of the pokemon that i want to get
const check = pokemon.id
const newPoke = getPokemon.includes(check);
// Here is the button that is getting disabled only if newPoke return true
<Button isDisabled={newPoke}/>
Everything work correctly when i refresh the page the buttons that i clicked previously get disabled but not onClick directly.
I think after i click i have to re-check for newPoke but i'm not sure how to include it in the button
You are using props to pass variable from parent to children(Button).
reactjs documentation states react props are read-only
If you are planing to change the values of newPoke then you should rethink your structure and maybe its best to use states in your example
For example here
<Button isDisabled="newPoke"></Button will only be checked at initialization stage since its a react prop. but if you used state which gets updated with every new action you can have a true one-way binding and your ui would reflect data changes quickly
store the newPoke in state and change it's value when the button is clicked. and use that value in button isDisabled prop. try something like this
state={
isDisabled: false;
}
handleClick=(isDisabled)=>{
this.setState({isDisabled});
}
//this is checking from my database if it include the id of the pokemon that i want to get
const check = pokemon.id
const newPoke = getPokemon.includes(check);
// Here is the button that is getting disabled only if newPoke return true
return(
<Button isDisabled={this.state.isDisabled} onClick={()=>this.handleClick(newPoke )}/>
);
i think if you want get value from database you can use componentDidMount().
and your value you can save while in state. and then in function handleClick you can change this state
for example :
handleClick = () => {
const value = this.state.valueFromDataBase
this setState({valueFromDataBase: false})
}
and in render you declare this value state
render(){
return(
<Button defaultValue={this.state.valueFromDataBase} onCLick={this.handleClick} />
)
}
please correct my answer if I am wrong in responding to your question
I have a react project, a recipe box, which includes the ability to open a recipe and add/delete ingredients. Here is a fiddle. You can click the recipe name to open the recipe. There is an edit button which reveals the delete button and gives the option to change the name of the ingredients. When the 'delete ingredient' button is pressed, the last ingredient appears to always be deleted, regardless of which ingredient is selected, but when the 'done' button is clicked and the editable input boxes change back to text, the correct change is shown, the proper ingredient deleted and the last ingredient remains. Though this works functionally, it's obviously not very UI friendly, and I wondered why this was happening. Any help would be great.
jsFiddle
class Input extends React.Component {
render() {
const array = this.props.update;
let booleanButton = null;
if (this.props.ingr) {
////////////////////////////
// here is the button's JSX
booleanButton = <button onClick=
{this.props.handleDeleteIngredient.bind(this, array)}>delete
ingredient</button>;
///////////////////////////
}
return (<div><form><input type="text" defaultValue={this.props.text}
onChange={this.props.onChange.bind(this, array)} /></form>{booleanButton}
</div>)
}
}
And the handler:
handleDeleteIngredient(data, e ) {
var key = data[2];
var ingrs = this.state.ingrs;
ingrs.splice(key, 1);
this.setState({ingrs:ingrs});
}
Your description is quiet confusing, and according the your fiddle code I think your problem is caused by not setting a good key for your list Item.
from what it looks in this line, you don't have a key={ingrs[i]} props, try set it to id see it will work, but making ingrediant name as key is probably not a good idea, try to give an actual id.
ingrList.push(<Input key={ingrs[i]} handleDeleteIngredient={this.handleDeleteIngredient.bind(this)} id={id} update={[this.props.objectIndex, "ingrs", i]} onChange={this.onInputChangeIng.bind(this)} text={ingrs[i]} />);
very new to react. you can say I have not yet started to think like React.
here is the problem:
<div>
<DropDown> </DropDown>
<Panel> </Panel>
</div>
In the dropdown, I select a value. Store it in state, as something as , currentLocation.
Then I go to Panel, hit a button, and I want to open a modal. When i open a modal, I need to pass the currentLocation to that model.
I can pass in arbitrary value to modal, but I cannot figure out a way to get the currently selected item from DropDown.
How do I get the value of the currently selected item to the Panel?
Am I even making sense?
When you call the setState in the dropdown that will force an update of the page.
Then if you call this.state in your component you should have the value you need there.
You should go over the basic tutorials to grasp the react basics.
But it goes like this:
getInitialState: function() {
return {
myVar: ''
//set your variables here
//getInitialState will get called before the component gets mounted
};
},
myCustomFunction: function(newVariable) {
this.setState({
myVar: newVariable
});
},
render: function() {
return (
<div>
<input
onChange={this.myCustomFunction}
/>
<MyCustomComponent myProp={this.state.myVar}/>
//everytime the state changes MyCustomComponent will have that new value as a prop
</div>
);
}
There is a lot of ambiguity in your question but I'll try for the simplest case.
You have a Panel component and a Dropdown component.
You want to the Panel to have access to a value that was set when the Dropdown was used.
Solution: When the Dropdown is actuated, it creates an Action that Stores the selected value.
When the modal button in the Panel is actuated, it creates an Action that requires the DropDownStore. Then it decides what to do based on that value.
The pattern I am loosely describing is known Facebook's Flux architecture which is basically just a more specific application architecture for React applications similar to pub/sub or an event bus.