Bővítse alkalmazását képfeltöltésekkel
Próbált már blogwebhelyet – vagy csak egy CRUD-webhelyet – létrehozni a MERN-verem segítségével? Szeretett volna képfeltöltést csatolni az alkalmazásához, majd az adatbázisba feltöltött képet megjeleníteni az ügyfélnek?
Hú, ez sok volt. De ma megmutatom, hogyan kell ezt megtenni a Cloudinary és a Multer segítségével.
Felhős
Mi az a Cloudinary, kérdezed?
A Cloudinary egy felhőszolgáltatás, amely lehetővé teszi, hogy egyszerűen töltsön fel képeket a felhőjükbe – amely ezután visszaad egy URL-t, amelyet elmentünk az adatbázisunkba, és megjelenítünk az ügyfélnek.
Ésszerűbb lesz, ha végrehajtjuk. Menjen a www.cloudinary.com oldalra, és hozzon létre fiókot. Ha végzett, feltétlenül vegye le ezeket a hitelesítő adatokat:
Cloud Name, API Key, API Secret
Ezek láthatóak lesznek az irányítópulton. Ezekre később szükségünk lesz, amikor beállítjuk a hátoldalunkat.
React alkalmazás létrehozása
Rendben, kezdjük a kezelőfelület létrehozásával.
Ehhez a create-react-appot fogjuk használni, hogy elindítsunk egy React starter projektet. A create-react-app használatával nem kell aggódnunk a webpack vagy a Babel beállítása miatt (mivel a create-react-app ezt alapértelmezés szerint rendezi).
Ha még nincs globálisan telepítve a Create-React-app a gépeden, akkor be kell írnod…
npm install -g create-react-app
… a termináljába. Ezután a terminálba írja be a következő parancsot:
npm install create-react-app cloudinary-app
A cloudinary-app
lesz a projekt neve – bármit elnevezhet, amit csak akar.
Ha ez kész, be kell mennünk a projekt mappába. Ehhez írja be a cd cloudinary-app
t a terminálba.
A projekt mappájában írja be a következő parancsot a terminálba: npm start
. Ez felpörgeti a fejlesztői szerverünket, és megnyitja a projektjét a localhost:3000 oldalon a böngészőjében.
Mivel már dolgozunk a kezelőfelületünkön, telepítsük a szükséges könyvtárakat. Szükségünk lesz az Axiókra a kezelőfelületen, hogy GET/POST
kérést küldhessünk a hátoldalunknak. Használjuk a Reduxot is (annak ellenére, hogy ez egy kis alkalmazás, és a Reactben csak a helyi állapotot használjuk).
Tudom, hogy ezt a legtöbben szeretnék egy nagyobb projektbe bevonni, ezért a Reduxot az államigazgatásra fogom használni. Ehhez írja be a következő parancsot a termináljába.
npm install axios react-redux redux redux-thunk --save
Hozzunk létre néhány fájlt is. Ezek nem szükségesek, de az oktatóanyag követéséhez egyszerűnek kell lenniük.
A src
mappában hozzon létre egy history.js
fájlt, és másolja ki a következő kódot:
import { createBrowserHistory } from “history”; export default createBrowserHistory();
Az előzményfájl minden útvonalhoz előzményobjektumot hoz létre kellékként. Ez teljes ellenőrzést biztosít a böngészési előzmények felett. Ez esetünkben akkor hasznos, ha egy művelet után átirányítjuk a felhasználót.
Most a következő fájl, amelyet létrehozunk, egy proxyfájl. Ez megkönnyíti a szerverünkhöz intézett HTTP-kéréseinket. Először hozzunk létre egy összetevő mappát a src
mappán belül. Az összetevők mappájában hozzon létre egy AxiosAPI.js
fájlt, és illessze be a következő kódot:
import axios from “axios”; export default axios.create({ baseURL: “http://localhost:5000" });
Ha valaha is HTTP-kéréseket kellett végrehajtania, tudja, hogy a hosszú URL beírása fájdalmas, így ez sokkal könnyebbé teszi. Rövidesen visszatérünk az összetevők mappájához.
Index.js → Redux Store beállítása
Most csatlakoztassuk Redux üzletünket.
Először menjünk a CRA által már létrehozott Index.js
fájlhoz. Ebben a fájlban cserélje ki a kódot a következő kódra. A Redux áruház az összes államunk tárolási helye.
import React from “react”; import ReactDOM from “react-dom”; import “./index.css”; import App from “./App”; import { Provider } from “react-redux”; import { createStore, applyMiddleware, compose } from “redux”; import reducers from “./reducers”; import reduxThunk from “redux-thunk”; const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; const store = createStore(reducers, composeEnhancers(applyMiddleware(reduxThunk))); ReactDOM.render(<Provider store={store}> <App /> </Provider>, document.getElementById(“root”));
Most létre kell hoznunk a reducers
és a actions
mappánkat.
A src
mappában hozzon létre egy reducers
és egy actions
mappát. Először alakítsuk ki cselekedeteinket. A actions
mappában hozzon létre egy új fájlt imageActions.js
néven. Ebben a fájlban létrehozzuk a műveleteinket, amelyeket elküldünk a reduktorunknak, hogy elmondják a Reduxnak, hogyan frissítse az alkalmazásunk állapotát.
Műveletek
Mielőtt létrehoznánk a műveletkészítőket, készítsük el a types.js
fájlunkat. A actions
mappában hozzon létre egy types.js file
fájlt. Ez nem kötelező, de mindig jó gyakorlat ezt megtenni arra az esetre, ha elgépelési hibát követne el az akciókészítők létrehozásakor.
Lapozzon át a imageActions.js
fájlra. Itt hozzuk létre a actions
fájlunkat.
import { ADD_IMAGE, GET_IMAGES, GET_ERRORS } from “./types”; import AxiosAPI from “../components/AxiosAPI”; import history from “../history”; //ADD IMAGE export const addImage = imageData => dispatch => { AxiosAPI.post(“/add”, imageData).then(res => dispatch({ type: ADD_IMAGE, payload: res.data })).catch(err => dispatch({ type: GET_ERRORS, payload: err.response.data })); history.push(“/”); }; //GET ALL IMAGES export const getAllImages = () => dispatch => { AxiosAPI.get(“/”).then(res => dispatch({ type: GET_IMAGES, payload: res.data })).catch(err => dispatch({ type: GET_IMAGES, payload: null })); };
Az átadott imageData
a formData
, amelyet később az űrlap komponensben fogunk használni, amely a cím és a kép lesz.
Csökkentők
Most állítsuk be a reduktorunkat.
Mivel ez egy kis alkalmazás, csak egy szűkítőnk lesz. De mivel sokan közületek valószínűleg nagyobb alkalmazásokat hoznak létre, több mint egy szűkítő lesz, és a combineReducers
értéket kell használnia a rootReducer
fájlban.
Mindenesetre a reducers
mappánkban létrehozhatunk egy index.js
fájlt. A reduktorok csak sima JavaScript objektumok.
Tehát adja hozzá a következő kódot a index.js
fájlba. Akkor is hasznos, ha a Redux DevTools szoftvert használja, hogy fizikailag megtekinthesse adatait a Redux áruházban. Másolja a következő kódot a imageActions.js
fájlba.
import { ADD_IMAGE, GET_IMAGES } from “../actions/types”; const initialState = { images: [] }; export default function(state = initialState, action) { switch (action.type) { case ADD_IMAGE: return {…state, images: [action.payload, …state.images]}; case GET_IMAGES: return { …state, images: action.payload }; default: return state; } }
Alkatrészek
Kezdjük azzal az űrlappal, amelyet a csatlakozáshoz használnunk kell, hogy a műveletkészítőnket az űrlapösszetevőhöz csatlakoztathassuk.
Hozzon létre egy Form.js
nevű fájlt az összetevők mappájában.
import React from “react”; import { connect } from “react-redux”; import { addImage } from “../actions/imageActions”; class Form extends React.Component { constructor(props) { super(props); this.state = { title: “”, image: “” }; this.onChangeTitle = this.onChangeTitle.bind(this); this.onChangeImage = this.onChangeImage.bind(this); this.onSubmit = this.onSubmit.bind(this); } onChangeTitle = e => { this.setState({ title: e.target.value }); }; onChangeImage = e => { this.setState({ image: e.target.files[0] }); }; onSubmit(e) { e.preventDefault(); let formData = new FormData(); formData.append(“title”, this.state.title); formData.append(“image”, this.state.image); this.props.addImage(formData); this.setState({ title: “”, image: “” }); } render() { return ( <div className=”form-container”> <form encType=”multipart/form-data” onSubmit={this.onSubmit}> <h2>Image Form</h2> <label className=”form-label”>Image Title</label> <input className=”form-input” placeholder=”Enter Image Title” type=”text” value={this.state.title} onChange={this.onChangeTitle} /> <label className=”form-label”>Choose an Image</label> <input type=”file” className=”form-input” onChange={this.onChangeImage} /> <button type=”submit” className=”submit-btn”>Submit!</button> </form> </div> ); } } export default connect(null,{ addImage })(Form);
Az ok, amiért a null
az első argumentum a connect függvényben, az az, hogy nem adunk át semmit. Általában a mapStateToProps
értéket adjuk át, ahogy az a AllImages.js
fájlban is látható.
Így kell kinéznie most az űrlapunknak!
Hozzon létre egy másik fájlt a AllImages.js
nevű összetevők alatt. Ez az összetevő felelős az űrlapról a szerverre küldött adatok megjelenítéséért. Ezután vesszük a szerverről visszaérkező adatokat, és megjelenítjük ebben a fájlban. Remélhetőleg ennek van értelme. Íme a AllImages.js
kódja:
Minden képünket egy tömbben tároljuk. A getAllImages
műveletkészítőt használjuk az adatok kihúzására a tömbből. Ezt úgy tesszük, hogy leképezzük a tömböt, és egyetlen képet ad vissza. A mapStateToProps
pontosan azt teszi, amit mond: leképezi az állapotot olyan kellékekre, amelyeket felhasználhatunk a komponensünkben.
Ennyi az alkalmazásunk elején. Most be kell állítanunk a hátoldalunkat, amit a cikk második részében fogunk megtenni.
A cikk 2. részének megtekintése.
Itt van egy link a „GitHub-tárházhoz”.