Reputation: 397
I've been trying to create a blog like website where user can add new post, save them and edit them later. I'm making this website in reactjs and redux. I've few confusions as to how to edit the post, like how will my website know that the user has clicked on this certain post to edit. To do I've used link from react router with the id at the end of the url but I'm not sure if it's the right way to do. Also, when I open the editor page of an existing post, it should load as it was last saved, i.e both the title input and the textarea should already be loaded with text when a user clicks on an already existing posts from the homepage.
I've created a codesandbox of the website. I'm not sure why all the lines in the switch statements in the reducer file is underlined with red.
this is my home.js file where the snippets will load
import React from "react";
import axios from "axios";
import { Link } from "react-router-dom";
import { onLoad, setEdit } from "./actions/posts";
import { connect } from "react-redux";
class Home extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
//Load all the snippets
onLoad();
}
render() {
const { snippets } = this.props;
return (
<div className="container">
<div className="row pt-5">
<div className="col-12 col-lg-6 offset-lg-3">
<h1 className="text-center">Snippets</h1>
</div>
</div>
<div className="row pt-5">
<div className="col-12 col-lg-6 offset-lg-3">
{snippets.map(snippet => {
return (
<div className="card my-3" key={snippet.snippetData.snippetId}>
<div className="card-header">{snippet.title}</div>
<div className="card-body">{snippet.snippetDescription}</div>
<div className="card-footer">
<div className="row">
<button
// onClick={() => this.handleEdit(snippet)}
className="btn btn-primary mx-3"
>
<Link to={`/editor/:${snippet.snippetData.snippetId}`}>
Edit
</Link>
</button>
</div>
</div>
</div>
);
})}
</div>
</div>
</div>
);
}
}
const mapStateToProps = state => ({
snippets: state.snippets,
snippetData: state.snippetData
});
export default connect(
mapStateToProps,
{ onLoad, setEdit }
)(Home);
editor.js page
import React, { Component } from "react";
import { connect } from "react-redux";
import { savePost, retrievePost } from "./actions/posts";
class Editor extends Component {
state = {
title: "",
enteredText: ""
};
componentDidMount() {
//Load the snippet
retrievePost(); // will it load the snippetId too?
}
handleChange = event => {
const { value } = event.target;
this.setState({
enteredText: value
});
};
// Save Snippet
performSave = snippetData => {
const { enteredText, title } = this.state;
savePost(snippetData.snippetId, enteredText, title); //is it the right way to send the parameters to save the post??
};
render() {
return (
<>
<input
type="text"
id="titletext"
placeholder="Enter title here"
limit-to="64"
className="inptxt"
onChange={title => this.setState({ title })}
/>
<button
className="btn savebtn"
onClick={() => this.handlePost({ ...this.state })}
>
Save Snippet
<i className="fas fa-save" />
</button>
<div
contentEditable={true}
spellCheck="false"
name="enteredText"
placeholder="Enter your text here"
onChange={this.handleChange}
/>
</>
);
}
}
const mapStateToProps = state => ({
snippetData: state.snippetData
});
export default connect(
mapStateToProps,
{ savePost, retrievePost }
)(Editor);
actions.js file
import { SAVE_POST, UPDATE_POST, RETRIEVE_POST, HOME_LOADED } from "./types";
export const savePost = ({
snippetId,
snippetDescription,
snippetTitle
}) => async dispatch => {
const config = {
headers: {
"Content-Type": "application/json"
}
};
let snippetData = { snippetId, snippetDescription, snippetTitle };
try {
if (snippetId == null) {
const res = await axios.post(
"/api/save",
JSON.stringify(snippetData),
config
);
snippetData.snippetId = res.data;
dispatch({
type: SAVE_POST,
payload: snippetData
});
} else {
const res = await axios.post(
"/api/update",
JSON.stringify(snippetData),
config
);
dispatch({
type: UPDATE_POST,
payload: snippetData
});
}
} catch (err) {
console.log(err);
}
};
// Retrieve post
export const retrievePost = snippetId => async dispatch => {
try {
const res = await axios.post(`/api/snippetdata/${id}`);
dispatch({
type: RETRIEVE_POST,
payload: res.data
});
} catch (err) {
console.error(err);
}
};
//Retrieve all the post
export const onLoad = () => async dispatch => {
try {
const res = await axios.post(`/api/mysnippets/`);
dispatch({
type: HOME_LOADED,
payload: res.data
});
} catch (err) {
console.error(err);
}
};
// edit a post
Upvotes: 1
Views: 1283
Reputation: 3228
First, I have fixed some problems for you:
https://codesandbox.io/s/amazing-bird-dd2mb
I did not fix the editor page, cuz I give up, it is meaningless to give you a working code while learning nothing.
I suggest you stop playing react now, you do not have enough experience to use a complex framework.
What problem your code has:
combineReducers
STOP WRITING CODE THAT YOU DO NOT UNDERSTAND
This project is too complex for a beginner.
I suggest you:
Repeat 3-6 but a todo list.
Then try to code a blog.
Upvotes: 2