How to handle a checkbox event in react redux? - reactjs

I ve to redirect to another page when ever the user checks the checkbox.
I am new to react-redux. Right now,all I know is to handle submit
button through dispatchaction but I am wondering how to handle
checkbox action?
export default class myReportForm extends BaseForm {
return(
</form>
</div>
);
}
}
Through handleSubmit in form, I could able to handle submit action. Can any one tell me how to handle checkbox . For example, when I ever click on Afloat , It should redirect me to another page or atleast some action should happen.

mapStateToProps and mapDispatchToActions are helper functions that will wire up the your component to the redux store. mapStateToProps links your component's properties to the state and mapDispatchToActions links its events to actions that can be dispatched.
http://redux.js.org/docs/basics/UsageWithReact.html#container-components
As ever (I'm always recommending this!) have a look at:
https://egghead.io/lessons/javascript-redux-generating-containers-with-connect-from-react-redux-visibletodolist (the whole course and its follow-up - Idiomtic Redux - are great).

Related

Render Component By Clicking Text Passed as Props

I am new to React and am trying to render a component when a user clicks on some text. The text is a state that's updated in a parent component using a form input and the useState React hook. I can find articles on rendering 'onClick' events, but this isn's a form with type submit or a button, it's just text that's passed down to it as a prop from a state higher up. Also a lot of tutorials seem to be outdated. What I would like to do is be able to click on the text and have it render a new component, with the effect of taking the user to a new 'page' in the browser. The rendered text I want to be able to click on is {user.contacts.username} in the code below. Any help much appreciated as I'm not sure which direction to go in.
import './Contacts.css';
import CreateTimer from './CreateTimer';
function Contacts(user) {
return (
<div className="Contacts">
{user.contacts.username}
</div>
);
}
export default Contacts;

React not rendering updated UI on state change

I'm working on a mini project where a user shall be able to edit book info. The app presents the user with a filter to choose Fiction or Science subject category. Once chosen, he is shown a list of books where he can change the details of the book by clicking the edit button. On editing, he can choose to either save or cancel the form details. This entire workflow is on a single page! I'm using React, Redux, and Redux-form for this purpose where component I- Selection category (Fiction, Science), component II- list of books for that category and component III- form to edit book details. See the attached image to imagine the app.
Working of the app: Once the user chooses Fiction/Science, an action is dispatched to list available books. Once he clicks Edit button for a book, another action is dispatched to display the form pre-filled with the book's values (so that the user can edit it).
The Problem: Unfortunately, my Edit form component is not rendering desired values due to unavailability of props to this component; even though I can see the success of my redux action with correct state/props.
Anatomy of code:
SubjectChoice.jsx
const mapDispatchToProps = dispatch => ({
fetchBooks: favoriteSubject => dispatch(getBooksList(favoriteSubject)),
fetchSubjects: _ => dispatch(getSubjectsList())
});
So, this component correctly dispatches getSubjectsList and I can use fetchSubjects as props on componentDidMount. Similarly, it dispatches another action getBooksList(favoriteSubject) according to the chosen subject and fetchBooks can be used as props on handleChange callback (These actions make API request; in fact, all does)
BookList.jsx
const mapDispatchToProps = dispatch => ({
fetchBookDetails: bookId => dispatch(getBookDetails(bookId))
});
So, this component correctly dispatches getBookDetails action on handleEdit which is Edit button callback.
BookEdit.jsx
const mapStateToProps = state => ({
book: state.book.bookDetails,
...
}...
render() {
const { bookDetails, loading, error } = this.props.book;
...
}
Now, this component keeps on waiting to re-render but it never receives the props. I see the actions, reducers dispatching correctly in the console (from BooksList.jsx component) but never see them reflecting on screen.
How SO answers are not helping me get out of this situation: I saw answers where it's specified that redux does a shallow comparison and if it doesn't find a subtle difference in the previous and next state then it skips rendering the app. However, as mentioned in the third step I see the action and reducer with previous and next state correctly.
If BookEdit isn't connected to the store or the props aren't being passed from a parent component you will not have access to them. Either connect your BookEdit...
import { connect } from 'react-redux;
...
const mapStateToProps = ({ book }) => {
const { bookDetails, loading, error } = book;
return { bookDetails, loading, error };
}
export default connect(mapStateToProps)(BookEdit);
Or pass them in from a parent connected component that is bringing in props from your store.
Every time Redux actions are dispatched, mapStateToProps will be executed. The connect function from react-redux will only re-render your component when the props from mapStateToProps are not equal to the previous props.

How to Differentiate input vs button state changes in react redux

I've got a simple login dialog that uses redux (just the dialog is shown below for reference). Each time the user types a character into either of the input fields a state change is fired through redux and when the button is pressed a state change also fires.
I plan on changing the state directly when the button is pressed to be something like "LoginPending", and when the REST call returns, the state will change to either "LoggedIn" or "LoginFailed".
My current plan is to add an if statement to the MapStateToProps method that check the old LoginPending status to see if that changed, and if it did, then dispatch the proper action (In reality I will execute a toast notify message).
My question is, "Is this the proper way to check for something like "logged in""? It seems awkward to do it in MapStateToProps, but since there are so many state changes happening (because of the onchange in the input elements), I can't think of a better place to do it.
class App extends Component {
....
render() {
return (
<div className="App">
<input onChange={this.handleChange('username')}/><br/>
<input onChange={this.handleChange('password')}/><br/><br/>
<button onClick={this.handleClick}>Login</button>
</div>
);
}
}
There are several ways to do it. One of the most popular way is to use redux-thunk. docs and example / official recommendation
Then all the logic will reside on the action creator:
export const exampleAction = (username, password) => (dispatch, getState) => {
dispatch({type: "exampleLoading"}); // the store sets a state variable so the view can render something while this "loading" state is true
doApiCall(username,password).then(response => {
// here the feedback message is added on the store, so my feedback manager can render the new feedback message
dispatch({type: "addFeedback", payload:{message:"success!", type:"success"}});
// here the store cleans up the "loading" variable and uses the api response if needed
dispatch({type: "exampleLoaded", payload: response});
});
}

React-redux: allowing users to give feedback on a component

I am returning a list of forecasts from my back end, which is rendered in a dashboard (I'm making the API call in componentWillMount()). Each forecast is rendered as a presentational component and has a like and dislike button. Once the user clicks on the button, a an Axios action is called which posts an event to the back end REST API saving this feedback.
As I see it, I don't need to deal with Redux's state here, unless I want to disable the buttons or otherwise change them when clicked. All I want to do here is to 1) trigger a CSS animation on the button (some sort of bounce) to let the user know he clicked it, and if the Axios action returns an error, I need to display it in an error section.
The issue is that I have not been able to figure out how to do this without going through the rigamarole of dispatching the Axios result to state, putting it through a reducer, then mapping state to props in the component, etc. This seems overkill for something this transitory, no?
Yes it does. As #ReiDien stated
you can just use axios directly without using any reducers.
As for the animation and the error message you can use your component's state to store these. You may need a container component to handle the state and its changes. Your handler ends up as something like:
handleLike = () => {
this.setState({
liked: true,
});
axios.post(...)
.catch((error) => {
this.setState({
error: error,
liked: false
});
});
}

How to redirect in Redux Action callback with React Router 4

I'm building a Front End React JS app that consumes from a back-end API, and I currently working on a basic login form. I'm using Redux and React-Router 4
Here is how it currently works:
User Fills out Login Form: User Inputs are stored as States on the LoginForm Component
Upon Submission, a LoginUser Action is dispatched: LoginForm user input states are submitted to the LoginUser Action. This action is responsible for submitting an AJAX request to the server. Upon successful response, the Redux Store is updated with all the relevant user information
In theory, when my AJAX request successfully receive user information after authentication and then subsequently updates the redux store, the user should be redirected to their dashboard page. Ideally this code should live in my LoginUser Action as a callback to my AJAX request.
My question is this: How do I programmatically redirect the user to another route in my action file? Is there a way to do this with React-Redux 4?
EDIT
So decided to keep the redirect state in my LoginForm component and create a function on the LoginForm component (redirectToDashboard())--this function would then be sent as a parameter to the fetchUser AJAX request that is sitting in my action file. I really feel like this is the best practice at the moment. Let me know if anyone else has other thoughts!
Special thanks to #alexander-borodin for giving me the guidance!
You can find a solution here
First of all, you should provide history to a context of your component:
static contextTypes = {
router: React.PropTypes.shape({
history: React.PropTypes.object.isRequired,
})
};
Then push new location in success callback function
export default YourComponent extends Component {
....
successCallback() {
this.context.router.history.push('/my-new-location')
}
....
}
The cleanest way is for React router to run a callback after route changes. Sadly they don't have that feature. There are 2 libraries which can do that using middleware - Redux-Saga and Redux Observable. The idea to listen for a state change, in this case a location change in history, and run a function.

Resources