disable semantic Button in react - reactjs

how to dynamically set semantic Button to disabled in react:
<Button disabled>click here<Button>
i tryed to set it with state but it gave me an error
this.setState({d:'disabled'})
return (<Button {this.state.d} >click here<Button>)

It's impossible to tell how your Button is handling disabled under the hood but assuming it´s working like the JSX element .
First, JSX elements are just functions that takes a set of arguments (props). So you still need to give it a disabled:boolean. As you can see below you need to provide a name and a value. Your attempt at {this.state.d} gives just the value true/false. Please look at the snippet below for how you can do it. Either explicit or by giving it a named variable or finally by spreading out an object.
class HelloWorldComponent extends React.Component {
constructor(){
super();
this.state = {
disabled: true
}
}
render() {
const disabled = this.state.disabled; //Pull out the value to a named variable
return (
<div>
<button disabled={false}>Button1</button>
<button disabled>Button2</button>
<button {...this.state}>Button3</button>
</div>
);
}
}
React.render(
<HelloWorldComponent/>,
document.getElementById('react_example')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script>
<div id="react_example"></div>

Related

Is it okay to call setState on a child component in React?

I have some text. When you click on that element a modal pops up that lets you edit that text. The easiest way to make this work is to call setState on the child to initialise the text.
The other way, although more awkward, is to create an initial text property and make the child set it's text based on this.
Is there anything wrong with directly calling setState on the child or should I use the second method?
Although it is recommended to keep the data of your react application "up" in the react dom (see more here https://reactjs.org/docs/lifting-state-up.html), I don't see anything wrong with the first aproach you mentioned.
If you have to store data that is very specific of a child I don't see anything wrong in keep that information in the child's state.
It seems that your modal doesn't need to have its own state, in which case you should use a stateless React component.
This is one way of passing the data around your app in the React way.
class ParentComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
initialText: "hello",
}
this.saveChildState = this.saveChildState.bind(this);
}
saveChildState(input) {
console.log(input);
// handle the input returned from child
}
render() {
return (
<div>
<ChildComponent
initialText={this.state.initialText}
save={this.saveChildState}
/>
</div>
);
}
}
function ChildComponent(props) {
return (
<div>
<input id="textInput" type="text" defaultValue={props.initialText}>
</input>
<button onClick={() => props.save(document.getElementById('textInput').value)}>
Save
</button>
</div>
)
}
Maybe I am misinterpreting your question, but I think it would make the most sense to keep the modal text always ready in your state. When you decide to show your modal, the text can just be passed into the modal.
class Test extends Component {
constructor() {
this.state = {
modalText: 'default text',
showModal: false
}
}
//Include some method to change the modal text
showModal() {
this.setState({showModal: true})
}
render(
return (
<div>
<button onClick={() => this.showModal()}>
Show Modal
</button>
{ this.state.showModal ? <Modal text={this.state.modalText}/> : null }
</div>
)
)
}

Changing background-image after onClick event in ReactJS

I have a component, let's say it looks like this:
return(
<div id="container"></div>
)
From the beginning it's background image is already set, let's say
#container{
background-image: url('./assets/container.jpg');}
Now I want to add another element inside the container div that will have onClick event firing function, that will do other things + changing the parent's background-image. Dummy code would be:
handleOnClick(){
doOtherStuff();
document.getElementById('container').style.backgroundImage = "url('./assets/container2.jpg')"}
return(
<div id="container">
<div onClick={()=> handleOnClick()}
</div>
)
Problems are:
It doesn't work, it changes background to blank screen,
After I leave the component and go back to it, it reverts to the old background. Is there any way to avoid that without having the background linked with state? I already have a lot of things in store and it will start to get messy real soon if I start adding more styles to it.
This is doable by giving your child the ability to change the state in your parent and holding that logic there. Also, it's much better to control your background shift by using this.setState. Just make it a boolean that controls which CSS id to use.
class Parent extends Component {
constructor() {
super()
this.state = {
defaultBackground: true
}
}
toggleChildBackground() {
const newBackground = !this.state.defaultBackground
this.setState({defaultBackground: newBackground})
}
render() {
return (
<div>
<Child
defaultBackground={this.state.defaultBackground}
toggleChildBackground={this.toggleChildBackground.bind(this)}
/>
</div>
)
}
}
class Child extends Component {
handleClick() {
this.props.toggleChildBackground()
}
render() {
return (
<div id={this.props.defaultBackground ? 'id1' : 'id2'}>
<button onClick={this.handleClick.bind(this)}>
change background
</button>
</div>
)
}
}

Can't get button component value onClick

I'm sure this is something trivial but I can't seem to figure out how to access the value of my button when the user clicks the button. When the page loads my list of buttons renders correctly with the unique values. When I click one of the buttons the function fires, however, the value returns undefined. Can someone show me what I'm doing wrong here?
Path: TestPage.jsx
import MyList from '../../components/MyList';
export default class TestPage extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.handleButtonClick = this.handleButtonClick.bind(this);
}
handleButtonClick(event) {
event.preventDefault();
console.log("button click", event.target.value);
}
render() {
return (
<div>
{this.props.lists.map((list) => (
<div key={list._id}>
<MyList
listCollection={list}
handleButtonClick={this.handleButtonClick}
/>
</div>
))}
</div>
);
}
}
Path: MyListComponent
const MyList = (props) => (
<div>
<Button onClick={props.handleButtonClick} value={props.listCollection._id}>{props.listCollection.title}</Button>
</div>
);
event.target.value is for getting values of HTML elements (like the content of an input box), not getting a React component's props. If would be easier if you just passed that value straight in:
handleButtonClick(value) {
console.log(value);
}
<Button onClick={() => props.handleButtonClick(props.listCollection._id)}>
{props.listCollection.title}
</Button>
It seems that you are not using the default button but instead some sort of customized component from another libray named Button.. if its a customezied component it wont work the same as the internatls might contain a button to render but when you are referencing the event you are doing it throug the Button component

Props not updated

I'm a new user of React and I try to dispatch a modification from my redux store into my components through a container component and props.
My problem is at the end, the data isn't updated. I tested and I figured out that in a Board component, I got the correct edited state (I edit a module's name in this.state.mlodules[1].name) but this value isn't sent in the Bloc component. Here is the render function of my Board component:
render() {
const modules = this.state.modules.map((module) => (
<Draggable key={module._id} x={module.position.x} y={module.position.y} inside={this.state.inside}>
<Bloc module={module} editModule={this.props.onModuleEdited(module._id)}/>
</Draggable>
));
return (
<div className="board"
onMouseLeave={this.mouseLeave}
onMouseEnter={this.mouseEnter}>
{modules}
</div>
);
}
And here is the render function of my Bloc component (I'm using a BlueprintJS editable text):
render() {
return (
<div className="pt-card pt-elevation-3 bloc">
<span onMouseDown={this.preventDrag}>
<EditableText
className="name"
defaultValue={this.props.module.name}
onChange={this.nameChanged}
/>
</span>
</div>
);
}
Any ideas ?
Thanks !
as i mentioned in my comment, you are assigning a defaultValue and not assigning a value prop.
according to their source code on line #77 you can see that there's a value prop.
Edit: As you can see in the docs, defaultValue is uncontrolled input where's value is a controlled input
I think, issue is defaultText. defaultText will assign the default text only on initial rendering it will not update the value. So instead of that assign the props value to value property.
Like this:
value = {this.props.module.name}
Note: But it will make the field read-only, if you don't update the props value (state of parent component) in onChange method.
Check this example, when you click on text 'Click Me' it will update the state value but text of input field will not change:
class App extends React.Component{
constructor(){
super();
this.state = {a:'hello'}
}
click(){
this.setState({a: 'world'},() => {
console.log('updated value: ', this.state.a)
})
}
render(){
return(
<div>
<Child value={this.state.a}/>
<p onClick={() => this.click()}>Click Me</p>
</div>
)
}
}
class Child extends React.Component{
render(){
console.log('this.props.value', this.props.value)
return(
<input defaultValue={this.props.value}/>
)
}
}
ReactDOM.render(<App/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'/>

i am not able retrieve array elements one at a time if i call them in my component all the elements are retrieved at a time

I want to load my array element when an event is occurred by referencing the key i tried different variables for the key but it would not accept all the elements of the array are being displayed if i give index as the key.
I am new to Reactjs and not very familiar with all the syntax and concept can somebody help me with the logic to solve this.
The event I am triggering is onClick or onChange.
`var Qstn =['A','B','C','D','E','F','G','H','I','J'];
<div>
{Qstn.map(function(Q,index){
return <span className="col-md-4 txt" key={index}>{Q}</span>
})}
</div>`
Ok I made a codepen with an example
http://codepen.io/lucaskatayama/pen/QGGwKR
It's using ES6 classes components, but it's easy to translate.
You need to set initial state to an empty array like [].
On click button, it call onClick() method which uses this.setState({}) to change component state.
When React notice state changes, it re-render the component.
class Hello extends React.Component {
constructor(){
super();
//Initial State
this.state = {
Qstn : []
}
}
onClick(){
//Called on click button
// Set state to whatever you want
this.setState({Qstn : ['A','B','C','D','E','F','G','H','I','J']})
}
render(){
let Qstn = this.state.Qstn; // load state and render
return (
<div>
<button onClick={() => this.onClick()}>Click</button>
<div>
{Qstn.map(function(Q,index){
return <span className="col-md-4 txt" key={index}>{Q}</span>
})}
</div>
</div>
)
}
}
ReactDOM.render(<Hello />, document.getElementById('container'))

Resources