Hello I have having a problem with my checkbox's staying checked when I check them. So what I want to be able to do is check and uncheck as I click the box. But once I check it it is stuck with a check and I can no longer do anything to it. Here is the relevant code!
import React, {Component} from 'react';
export default class ResolutionSingle extends Component {
toggleChecked() {
Meteor.call('toggleResolution', this.props.resolution._id, this.props.resolution.copmlete);
}
deleteResolution() {
Meteor.call('deleteResolution', this.props.resolution._id);
}
render() {
return (
<li>
<input type="checkbox"
readOnly={true}
checked={this.props.resolution.complete}
onClick={this.toggleChecked.bind(this)} />
{this.props.resolution.text}
<button className="btn-cancel"
onClick={this.deleteResolution.bind(this)}>
×
</button>
</li>
)
}
}
Here are the methods
Meteor.methods({
addResolution(resolution) {
Resolutions.insert({
text: resolution,
complete: false,
createAt: new Date()
});
},
toggleResolution(id, status) {
Resolutions.update(id, {
$set: {complete: !status}
});
},
deleteResolution(id) {
Resolutions.remove(id);
}
});
Here is the main wrapper
import React from 'react';
import ReactDOM from 'react-dom';
import TrackerReact from 'meteor/ultimatejs:tracker-react';
import ResolutionsForm from './ResolutionsForm.jsx';
import ResolutionSingle from './ResolutionSingle.jsx';
Resolutions = new Mongo.Collection("resolutions");
export default class ResolutionsWrapper extends TrackerReact(React.Component) {
constructor(){
super();
this.state = {
subscription: {
resolutions: Meteor.subscribe("allResolutions")
}
}
}
componentWillUnmount() {
this.state.subscription.resolutions.stop();
}
resolutions() {
return Resolutions.find().fetch();
}
render(){
return (
<div>
<h1>My Resolutions</h1>
<ResolutionsForm />
<ul className="resolutions">
{this.resolutions().map( (resolution)=>{
return <ResolutionSingle key={resolution._id} resolution={resolution} />
})}
</ul>
</div>
)
}
}
You have a typo in your code.
Meteor.call('toggleResolution', this.props.resolution._id, this.props.resolution.copmlete);
It should be complete instead of copmlete. In order to avoid errors like that in the future, you can use check functions in your Meteor methods.
Related
import React from 'react'
export default () => {
function clickHandler() {
console.log('Button clicked')
}
return (
<div>
<button onClick={clickHandler}>Click</button>
</div>
)
}
In the above code we see that a function has been passed to the onClick.In the same way to the onClick I need to pass a diffrent component which is present in the same src. This component consists of a .js and a .css file.Could you please help me out with it. Thanks in advance
If you don't mind using classes instead of functions, your other component should look like this:
import React from 'react'
class ShowThisAfterClick extends React.Component {
return (
<div>
<p>This is what you want to show</p>
</div>
)
}
export default ShowThisAfterClick
And now you should update the component you've shown:
import React from 'react'
import ShowThisAfterClick from './where/you/put/the/ShowThisAfterClick.js'
class Main extends React.Component {
constructor(props){
super(props)
this.state = { isButtonClicked: false }
this.clickHandler = this.clickhandler.bind(this)
}
clickHandler() {
this.setState({ isButtonClicked: true })
}
render() {
const { isButtonClicked } = this.state
return (
<div>
<button onClick={ this.clickHandler }>Click</button>
{ isButtonClicked ? <ShowThisAfterClick /> : ''}
</div>
)
}
}
export default Main
If you want to keep using functions, then I would kindly suggest to read the manual, it is more than well written.
Im making my first react ptoject. Im new in JS, HTML, CSS and even web app programing.
What i try to do, is to display some infomration on button click.
I have an API, that looks like this:
endpoint: https://localhost:44344/api/Projects
My Data from it:
[{"id":1,"name":"Mini Jira","description":"Description for first project in list","tasks":null},{"id":2,"name":"Farm","description":"Description for second one","tasks":null}]
And im fine with that, i can get it easily by axios in my react app.
Now i will show you my Project.js Component:
import React, { Component } from "react";
import { ListGroupItem, Button, ButtonToolbar } from "react-bootstrap";
import ProjectDetails from "./ProjectDetails";
class Project extends Component {
render() {
return (
<ButtonToolbar>
<ListGroupItem>{this.props.project.name}</ListGroupItem>
<Button onClick={Here i want to display new component with details }bsStyle="primary">Details</Button>
</ButtonToolbar>
);
}
}
export default Project;
I have all data from api in project type.
My question is, how to display component that i named ProjectDetails.js on button click? I want to show all data stored in project from my api in separate view (new page or somethig like that).
View looks like this:
Thanks for any advices!
EDIT:
based on #Axnyff answer, i edited Project.js. it works ok. But when i want to (for testing) displat project.name, i get error map of undefined. My ProjectDetails.js:
import React, { Component } from "react";
class ProjectDetails extends Component {
state = {};
render() {
return <li>{this.props.project.name}</li>;
}
}
export default ProjectDetails;
EDIT2:
In Project.js in #Axnyff answet i just edited that line:
{this.state.showDetails && (
<ProjectDetails project={this.props.project} />
)}
i passed project by props, now it works like i want too. After click it displays project.name that i clicked on.
You should use state in your React component.
Let's create a field called showDetails in your state.
You can initialize it in your constructor with
constructor(props) {
super(props); // needed in javascript constructors
this.state = {
showDetails: false,
};
}
Then you need to modify the onClick to set that state to true
<Button onClick={() => this.setState({ showDetails : true })} bsStyle="primary">Details</Button>
And then use that state to show or not the ProjectDetails:
{ showDetails && <ProjectDetails /> }
The full component should look like
import React, { Component } from "react";
import { ListGroupItem, Button, ButtonToolbar } from "react-bootstrap";
import ProjectDetails from "./ProjectDetails";
class Project extends Component {
constructor(props) {
super(props); // needed in javascript constructors
this.state = {
showDetails: false,
};
}
render() {
return (
<ButtonToolbar>
<ListGroupItem>{this.props.project.name}</ListGroupItem>
<Button onClick={() => this.setState({ showDetails : true })} bsStyle="primary">Details</Button>
{ this.state.showDetails && <ProjectDetails /> }
</ButtonToolbar>
);
}
}
export default Project;
You can then modify the logic to add a toggling effect etc.
If you haven't done it, you should probably follow the official tutorial
function Bar() {
return <h1>I will be shown on click!</h1>;
}
class Foo extends React.Component {
constructor() {
super();
this.state = { showComponent: false };
}
handleClick = () => {
this.setState({ showComponent: !this.state.showComponent });
};
render() {
return (
<div>
{this.state.showComponent && <Bar />}
<button onClick={this.handleClick}>click</button>
</div>
);
}
}
ReactDOM.render(<Foo />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
I have below codes
chat.js
import React from 'react';
import '../styles/Chat.css';
import Web from '../services/Web';
class Chat extends React.Component {
constructor(props) {
super(props);
this.state = {
msg:''
};
this.sendMessage = this.sendMessage.bind(this);
}
sendMessage () {
this.props.updatecommentText(this.refs.newText.value, this.props.index);
this.setState({ msg: '' });
}
render() {
return (
<div className="Chat-container">
<div className="Chat-row">
<div className="Chat-column">
<div className="Chat-card">
<div className="Chat-body">
<div className="Chat-title">React Based Chatbot</div>
<div className="Chat-messages">
{ this.props.children }
</div>
</div>
<div className="Chat-footer">
<textarea className="Chat-input" ref="newText"></textarea>
<button className="Chat-submit" onClick={this.sendMessage} defaultValue={ this.props.children }>Send</button>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Chat;
Web.js
import React, { Component } from 'react';
import PropTypes from "prop-types";
import { Link } from "react-router-dom";
import Chat from '../components/Chat';
class Web extends React.Component {
constructor(props){
super(props);
this.state = {
messages:["Hi, How can I help you ?"
]
};
this.sendtobot = this.sendtobot.bind(this);
}
sendtobot(newText, i){
var arr = this.state.messages
arr.push(newText)
this.setState({messages: arr})
}
eachMessage(message, i){
return (<Chat key={i} index={i} updatecommentText={ this.sendtobot.bind(this) }>{ message }</Chat>);
}
render(){
return(
<div>
{this.state.messages.map(this.eachMessage.bind(this))}
</div>
)
}
}
export default Web;
I wanted to take the input from the Chat.js and send it to Web.js and push that value to array messages and then again render that array in the this.props.children in Chat.js
But, while running the code, I am getting an error this.props.updatecommentText is not a function.
Can someone please help me with this.
You have bind this.sendtobot twice. It should be only in the constructor.
like this
eachMessage(message, i){
return (
<Chat key={i} index={i} updatecommentText={this.sendtobot}>
{ message }
</Chat>
);
}
Your code seems to work.
Here is a sandbox with your code.
I'm not sure it works as you would expect, but it works without errors.
By changing this 3 functions in Web component, it starting to look like a chat with only one textarea
sendtobot(newText, i) {
this.setState({ messages: [...this.state.messages, newText] })
}
eachMessage(message, i) {
return (<p>{message}</p>);
}
render() {
return (
<div>
{this.state.messages.map(this.eachMessage.bind(this))}
<Chat updatecommentText={this.sendtobot}/>
</div>
)
}
You can pass child's component state to parent component using redux also as global state.
I am using the react-chat-widget and trying to call a function in the base class of my application from a custom component rendered by the renderCustomComponent function of the widget.
Here is the code for the base class:
import React, { Component } from 'react';
import { Widget, handleNewUserMessage, addResponseMessage, addUserMessage, renderCustomComponent } from 'react-chat-widget';
import 'react-chat-widget/lib/styles.css';
import Reply from './Reply.js';
class App extends Component {
handleNewUserMessage = (newMessage) => {
renderCustomComponent(Reply, this.correct);
}
correct = () => {
console.log("success");
}
render() {
return (
<div className="App">
<Background />
<Widget
handleNewUserMessage={this.handleNewUserMessage}
/>
</div>
);
}
}
export default App;
And here is the code for the custom component Reply:
import React, { Component } from 'react';
import { Widget, addResponseMessage, renderCustomComponent, addUserMessage } from 'react-chat-widget';
class Reply extends Component {
constructor(props) {
super(props);
}
sendQuickReply = (reply) => {
console.log(this.props); //returns empty object
//this.props.correct(); <-- should be called
};
render() {
return (
<div className="message">
<div key="x" className={"response"}onClick={this.sendQuickReply.bind(this, "xx")}>xx</div>
</div>)
}
}
export default Reply;
According to ReactJS call parent method this should work. However, when I print the this.props object it is empty, although the documentation of the renderCustomComponent method states that the second argument of the component to render are the props that the component needs (in this case the parent class function).
Where have I gone wrong?
The second parameter is considered as props, but it is expected to be an object. you would pass it like
handleNewUserMessage = (newMessage) => {
renderCustomComponent(Reply, {correct: this.correct});
}
I have this code in Reactjs that display a label with a checkbox
import React, { Component, PropTypes } from 'react';
class Test extends Component {
constructor() {
super(...arguments);
}
checkboxClicked(e) {
this.props.test.clicked = e.target.checked;
}
render() {
return (
<li>
<label>
<input type="checkbox" value={this.props.test.id} checked={this.props.test.clicked} onChange={this.checkboxClicked.bind(this)} />
{this.props.test.text}
</label>
</li>
);
}
}
export default Test;
The checkbox and text is well displayed, but when I click on it, it refused to get checked. The value of this.props.test.clicked is changed but not the ui in the browser.
Can somebody tell me that I am missing?
It's not recommended to change props.
Try to use state instead.
import React, { Component, PropTypes } from 'react';
class Test extends Component {
constructor() {
super(...arguments);
this.state = { checked: this.props.test.clicked };
}
checkboxClicked(e) {
this.setState({checked : e.target.checked});
}
render() {
return (
<li>
<label>
<input type="checkbox" value={this.props.test.id} checked={this.state.checked} onChange={this.checkboxClicked.bind(this)} />
{this.props.test.text}
</label>
</li>
);
}
}
export default Test;