
npx create-react-app meme-generator index.js and App.js . You can easily delete this code and try to write it yourself in order to test yourself in the implementation of standard mechanisms of React-applications. * {   box-sizing: border-box; } body {   margin: 0;   background-color: whitesmoke; } header {   height: 100px;   display: flex;   align-items: center;   background: #6441A5;  /* fallback for old browsers */   background: -webkit-linear-gradient(to right, #2a0845, #6441A5);  /* Chrome 10-25, Safari 5.1-6 */   background: linear-gradient(to right, #2a0845, #6441A5); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ } header > img {   height: 80%;   margin-left: 10%; } header > p {   font-family: VT323, monospace;   color: whitesmoke;   font-size: 50px;   margin-left: 60px; } .meme {   position: relative;   width: 90%;   margin: auto; } .meme > img {   width: 100%; } .meme > h2 {   position: absolute;   width: 80%;   text-align: center;   left: 50%;   transform: translateX(-50%);   margin: 15px 0;   padding: 0 5px;   font-family: impact, sans-serif;   font-size: 2em;   text-transform: uppercase;   color: white;   letter-spacing: 1px;   text-shadow:       2px 2px 0 #000,       -2px -2px 0 #000,       2px -2px 0 #000,       -2px 2px 0 #000,       0 2px 0 #000,       2px 0 0 #000,       0 -2px 0 #000,       -2px 0 0 #000,       2px 2px 5px #000; } .meme > .bottom {   bottom: 0; } .meme > .top {   top: 0; } .meme-form {   width: 90%;   margin: 20px auto;   display: flex;   justify-content: space-between; } .meme-form > input {   width: 45%;   height: 40px; } .meme-form > button {   border: none;   font-family: VT323, monospace;   font-size: 25px;   letter-spacing: 1.5px;   color: white;   background: #6441A5; } .meme-form > input::-webkit-input-placeholder { /* Chrome/Opera/Safari */ font-family: VT323, monospace; font-size: 25px; text-align: cen } .meme-form > input::-moz-placeholder { /* Firefox 19+ */ font-family: VT323, monospace; font-size: 25px; text-align: cen } .meme-form > input:-ms-input-placeholder { /* IE 10+ */ font-family: VT323, monospace; font-size: 25px; text-align: cen } .meme-form > input:-moz-placeholder { /* Firefox 18- */ font-family: VT323, monospace; font-size: 25px; text-align: cen } index.css file already present in the project and index.css in the index.js file.index.js and App.js files are now empty, you, as the first task, are invited to write the index.js code index.js , create the simplest component in App.js and display it in index.js .index.js : import React from "react" import ReactDOM from "react-dom" import './index.css' import App from "./App" ReactDOM.render(<App />, document.getElementById("root")) React and ReactDOM , import styles from index.css and the App component. After that, using the ReactDOM.render() method, we ReactDOM.render() what the App component forms into the element of the index.html page with the root identifier ( <div id="root"></div> ).App.js file looks like: import React from "react" function App() {   return (       <h1>Hello world!</h1>   ) } export default App 
Header component that will be used to display the application header.MemeGenerator , which will solve the main tasks assigned to the application. Namely, API calls will be made here. The application data will also be stored here.Header.js file: import React from "react" function Header() {   return (       <h1>HEADER</h1>   ) } export default Header MemeGenerator.js file: import React, {Component} from "react" class MemeGenerator extends Component {   constructor() {       super()       this.state ={}   }     render() {       return (           <h1>MEME GENERATOR SECTION</h1>       )   } } export default MemeGenerator MemeGenerator component, will use the component based on the class. There is a constructor in which we initialize the state with an empty object.App.js and return the markup from the functional component App , which uses instances of these components, not forgetting that if the functional component returns several elements, they need to be wrapped into something. In our case, this is the <div> . Here is the updated App.js code: import React from "react" import Header from "./Header" import MemeGenerator from "./MemeGenerator" function App() {   return (       <div>           <Header />           <MemeGenerator />       </div>   ) } export default App 
Header component. Here we use the HTML5 <header> semantic element. This tag will contain the image and text. Now the code of the Header.js file will look like this: import React from "react" function Header() {   return (       <header>           <img               src="http://www.pngall.com/wp-content/uploads/2016/05/Trollface.png"               alt="Problem?"           />           <p>Meme Generator</p>       </header>   ) } export default Header 
index.js . The work on the Header component is now complete.MemeGenerator . Now you are invited to independently initialize the state of this component by writing the following data into it:topText property).bottomText property).randomImage property, which needs to be initialized by the link http://i.imgflip.com/1bij.jpg ).MemeGenerator.js code will be after the state is initialized: import React, {Component} from "react" class MemeGenerator extends Component {   constructor() {       super()       this.state = {           topText: "",           bottomText: "",           randomImg: "http://i.imgflip.com/1bij.jpg"       }   }     render() {       return (           <h1>MEME GENERATOR SECTION</h1>       )   } } export default MemeGenerator MemeGenerator component:response.data.memes in a new state property ( allMemeImgs ). {   "success":true,  "data":{      "memes":[         {           "id":"112126428",           "name":"Distracted Boyfriend",           "url":"https:\/\/i.imgflip.com\/1ur9b0.jpg",           "width":1200,           "height":800,           "box_count":3        },        {           "id":"87743020",           "name":"Two Buttons",           "url":"https:\/\/i.imgflip.com\/1g8my4.jpg",           "width":600,           "height":908,           "box_count":2        },        {           "id":"129242436",           "name":"Change My Mind",           "url":"https:\/\/i.imgflip.com\/24y43o.jpg",           "width":482,           "height":361,           "box_count":2        },        β¦.  ]  } } componentDidMount() . Here we will use the standard fetch() method to access the API. It returns a promise. After the data is loaded, the response object will be available to us, we extract the memes array from it and put it in the new state property allMemeImgs , initialized with an empty array. Since this data is not yet used to form something that is displayed on the screen, we will display the first element of the array in the console to check the correctness of the data loading mechanism.MemeGenerator component at this stage of the work: import React, {Component} from "react" class MemeGenerator extends Component {   constructor() {       super()       this.state = {           topText: "",           bottomText: "",           randomImg: "http://i.imgflip.com/1bij.jpg",           allMemeImgs: []       }   }     componentDidMount() {       fetch("https://api.imgflip.com/get_memes")           .then(response => response.json())           .then(response => {               const {memes} = response.data               console.log(memes[0])               this.setState({ allMemeImgs: memes })           })   }     render() {       return (           <h1>MEME GENERATOR SECTION</h1>       )   } } export default MemeGenerator 
url property, which gives access to the link to download the image.
MemeGenerator component code shown below, which differs from the above code of this component in that the form blank has been added here, create a couple of text fields, topText and bottomText . Note that these must be managed components. Add the necessary attributes to them. Create an onChange event onChange these fields, where you need to update the corresponding state properties as you enter text in them. import React, {Component} from "react" class MemeGenerator extends Component {   constructor() {       super()       this.state = {           topText: "",           bottomText: "",           randomImg: "http://i.imgflip.com/1bij.jpg",           allMemeImgs: []       }   }     componentDidMount() {       fetch("https://api.imgflip.com/get_memes")           .then(response => response.json())           .then(response => {               const {memes} = response.data               this.setState({ allMemeImgs: memes })           })   }     render() {       return (           <div>               <form className="meme-form">                   {                       //                        }                                 <button>Gen</button>               </form>           </div>       )   } } export default MemeGenerator render() method, we enclosed it in braces in order to indicate to the system that it should take the given fragment as JavaScript code. import React, {Component} from "react" class MemeGenerator extends Component {   constructor() {       super()       this.state = {           topText: "",           bottomText: "",           randomImg: "http://i.imgflip.com/1bij.jpg",           allMemeImgs: []       }       this.handleChange = this.handleChange.bind(this)   }     componentDidMount() {       fetch("https://api.imgflip.com/get_memes")           .then(response => response.json())           .then(response => {               const {memes} = response.data               this.setState({ allMemeImgs: memes })           })   }     handleChange(event) {       const {name, value} = event.target       this.setState({ [name]: value })   }     render() {       return (           <div>               <form className="meme-form">                   <input                       type="text"                       name="topText"                       placeholder="Top Text"                       value={this.state.topText}                       onChange={this.handleChange}                   />                   <input                       type="text"                       name="bottomText"                       placeholder="Bottom Text"                       value={this.state.bottomText}                       onChange={this.handleChange}                   />                                 <button>Gen</button>               </form>           </div>       )   } } export default MemeGenerator 
console.log() command.Gen button, randomly select an image from this array and form a meme.MemeGenerator component. Here, in the render() method, below the form description code, there is a <div> element that includes an <img> element that displays an image, and a pair of <h2> elements that display labels. The <div> and <h2> elements are designed using the styles that we added to the project at the very beginning of working on it. import React, {Component} from "react" class MemeGenerator extends Component {   constructor() {       super()       this.state = {           topText: "",           bottomText: "",           randomImg: "http://i.imgflip.com/1bij.jpg",           allMemeImgs: []       }       this.handleChange = this.handleChange.bind(this)   }     componentDidMount() {       fetch("https://api.imgflip.com/get_memes")           .then(response => response.json())           .then(response => {               const {memes} = response.data               this.setState({ allMemeImgs: memes })           })   }     handleChange(event) {       const {name, value} = event.target       this.setState({ [name]: value })   }     render() {       return (           <div>               <form className="meme-form">                   <input                       type="text"                       name="topText"                       placeholder="Top Text"                       value={this.state.topText}                       onChange={this.handleChange}                   />                   <input                       type="text"                       name="bottomText"                       placeholder="Bottom Text"                       value={this.state.bottomText}                       onChange={this.handleChange}                   />                                 <button>Gen</button>               </form>               <div className="meme">                   <img align="center" src={this.state.randomImg} alt="" />                   <h2 className="top">{this.state.topText}</h2>                   <h2 className="bottom">{this.state.bottomText}</h2>               </div>           </div>       )   } } export default MemeGenerator 
allMemeImgs . Let's try to enter something in the text fields.
Gen button from the array with the image data, a random image would be selected and loaded into the <img> element present on the page below the text input fields.Gen button. This method should choose one of the images, information about which is stored in the state property allMemeImgs , and then perform actions that allow you to display this image in the <img> element located below the text input fields. allMemeImgs in allMemeImgs that allMemeImgs stores an array of objects that describe images, and that each object from this array has a url property. import React, {Component} from "react" class MemeGenerator extends Component {   constructor() {       super()       this.state = {           topText: "",           bottomText: "",           randomImg: "http://i.imgflip.com/1bij.jpg",           allMemeImgs: []       }       this.handleChange = this.handleChange.bind(this)       this.handleSubmit = this.handleSubmit.bind(this)   }     componentDidMount() {       fetch("https://api.imgflip.com/get_memes")           .then(response => response.json())           .then(response => {               const {memes} = response.data               this.setState({ allMemeImgs: memes })           })   }     handleChange(event) {       const {name, value} = event.target       this.setState({ [name]: value })   }     handleSubmit(event) {       event.preventDefault()       const randNum = Math.floor(Math.random() * this.state.allMemeImgs.length)       const randMemeImg = this.state.allMemeImgs[randNum].url       this.setState({ randomImg: randMemeImg })   }     render() {       return (           <div>               <form className="meme-form" onSubmit={this.handleSubmit}>                   <input                       type="text"                       name="topText"                       placeholder="Top Text"                       value={this.state.topText}                       onChange={this.handleChange}                   />                   <input                       type="text"                       name="bottomText"                       placeholder="Bottom Text"                       value={this.state.bottomText}                       onChange={this.handleChange}                   />                                 <button>Gen</button>               </form>               <div className="meme">                   <img align="center" src={this.state.randomImg} alt="" />                   <h2 className="top">{this.state.topText}</h2>                   <h2 className="bottom">{this.state.bottomText}</h2>               </div>           </div>       )   } } export default MemeGenerator Gen button can be assigned an event handler that occurs when you click on it, as is done when working with any other buttons. However, given that this button is used to submit the form, it would be better to use the form's onSubmit event handler. In this handler, handleSubmit() , we call the event event event.preventDefault() to cancel the standard form event.preventDefault() procedure during which the page is reloaded. Next, we get a random number in the range from 0 to the value corresponding to the index of the last element of the array allMemeImgs and use this number to refer to the element with the corresponding index. Referring to the element that is an object, we get the property of this object url and write it in the state property randomImg . After that, the component is re-rendered and the page appearance changes.
Source: https://habr.com/ru/post/447136/
All Articles