Markdown component not rendering from content stored in State - reactjs

I'm attempting to render Markdown using 'react-markdown' and setting the content as state. This state is set in componentDidMount, and console logging the state successfully logs the content like so (it's just nonsense as this is an example while I set it up):
**Bold text**
*Italic text*
__Underlined text__
~~Strikethrough text~~
List
- Hello
Numbered list
1. Number one
Image
![AA.png](/uploads/AA_6834a9a7ea.png)
However, when I then try to render my content in my component, it just comes through as blank.... Which I can't figure out why it's happening.
Here's my component code:
import React, { Component } from 'react';
import Strapi from 'strapi-sdk-javascript/build/main';
import Moment from 'react-moment';
import Markdown from 'react-markdown';
import './blog.css';
import MainHeader from '../global/main-header'
import Footer from '../global/footer'
class IndividualBlogPost extends Component {
constructor(props) {
super(props)
this.state = {
title: '',
description: '',
datePosted: '',
content: '',
author: ''
}
}
async componentDidMount() {
const params = this.props.match.params.id
try {
const posts = await strapiInstance.getEntry('blog-posts', params)
this.setState({
title: posts.Title,
description: posts.Description,
datePosted: posts.created_at,
content: posts.Content,
author: `${posts.created_by.firstname} ${posts.created_by.lastname}`
})
console.log(this.state.content)
}
catch(err) {
console.log(err)
}
}
render() {
const content = this.state.content
return (
<div>
<MainHeader />
<section className="individual-blogpost-section">
<div className="individual-blogpost-container">
<h1 className="individual-blogpost-heading">{this.state.title}</h1>
<div className="individual-blogpost-author-datePosted">
<p className="individual-blog-post-title-paragraph">{this.state.author} | <Moment format="MMM Do YYYY">{this.state.datePosted}</Moment></p>
</div>
<h4 className="individual-blogpost-description">{this.state.description}</h4>
<div className="individual-blogpost-content">
<Markdown src={content} />
</div>
</div>
</section>
<Footer />
</div>
)
}
}
export default IndividualBlogPost
As you can hopefully see, I'm attempting to set a const named content as this.state.content, and then passing the source of the markdown in to the Markdown component.
This is the first time I'm using Markdown, so I'm probably doing something obviously wrong, but any help would be appreciated!

According to their documentation, the content is actually passed as children to Markdown.
So you can do this:
<div className="individual-blogpost-content">
<Markdown >
{content}
</Markdown>
</div>

i am add package npm i remarkable.
and wrote this code
import React from "react";
import { Remarkable } from "remarkable";
class MarkdownEditor extends React.Component {
constructor(props) {
super(props);
this.md = new Remarkable();
this.handleChange = this.handleChange.bind(this);
this.state = { value: "Hello, **world**!" };
}
handleChange(e) {
this.setState({ value: e.target.value });
}
getRawMarkup() {
return { __html: this.md.render(this.state.value) };
}
render() {
return (
<div className="MarkdownEditor">
<h3>Input</h3>
<label htmlFor="markdown-content">Enter some markdown</label>
<textarea
id="markdown-content"
onChange={this.handleChange}
defaultValue={this.state.value}
/>
<h3>Output</h3>
<div
className="content"
dangerouslySetInnerHTML={this.getRawMarkup()}
/>
</div>
);
}
}
export default MarkdownEditor;
Work Demo

Related

REACT - Why isnt my Filter Method Working

Im trying to simply create a search and results feature for an app. The value of the input should reflect the components listed in the CardList Array. The filter doesn't seem to update the CardList. I've logged steps along the way and I've come to the conclusion that its the filter I set up. I cant seem to figure out why it wont filter the list.
import React, {Component} from 'react';
import CardList from './CardList';
import {robots} from './robots';
import './index.css';
class App extends Component {
constructor() {
super()
this.state = {
robots: robots,
searchfield: ''
}
}
onSearchChange = (event) => {
this.setState({ searchfield: event.target.value });
}
render() {
const filteredRobots = this.state.robots.filter(robot => {
return robot.name.toLowerCase().includes(this.state.searchfield.toLowerCase());
});
return (
<div className="appAlign">
<h1 className="appTitle">RoboFriends</h1>
<input
className="searchBox"
type="search"
placeholder="Search Robots"
onChange={this.onSearchChange}
/>
<CardList robots={filteredRobots} />
</div>
);
}
}
export default App;
The error is not caused by the filter function as I have tested it and it works. It most probably lies with the robots data-set. I have slightly modified the filter function here.
import React, { Component } from "react";
import CardList from "./CardList";
import { robots } from "./robots";
class App extends Component {
constructor() {
super();
this.state = {
robots: robots,
searchfield: ""
};
}
onSearchChange = event => {
this.setState({ searchfield: event.target.value });
};
render() {
const filteredRobots = this.state.robots.filter(robot =>
robot.name.toLowerCase().includes(this.state.searchfield.toLowerCase())
);
return (
<div className="appAlign">
<h1 className="appTitle">RoboFriends</h1>
<input
className="searchBox"
type="search"
placeholder="Search Robots"
onChange={this.onSearchChange}
/>
<CardList robots={filteredRobots} />
</div>
);
}
}
export default App;
I have made a sandbox with your code which has a sample robots data and a Card that renders the filtered data-set. Take a look.

React - Cannot render list item that is retrieved from API

I am writing a react application that outputs a list of books (image, title, category, and description).
My search bar and booklist are sibling components and the search bar will pass data to the booklist.
when clicking the search button, only "Sample Category" shows up but not anything else. There is no problem accessing the API and the data is not null.
Here is a sample API output: https://www.googleapis.com/books/v1/volumes?q=lordoftherings
My code is the following:
// App
import React, { Component } from 'react';
import Axios from 'axios';
import './App.css';
import SearchBar from './SearchBar';
import BookList from './BookList';
class App extends Component {
constructor(props) {
super(props);
this.state = {
books: []
};
this.search = this.search.bind(this);
}
search(title) {
const promise = Axios.get('https://www.googleapis.com/books/v1/volumes?q=' + title);
promise.then((response) => {
const books = response.data.items;
this.setState({ books: books });
console.log(this.state.books);
})
};
render() {
return (
<div className="App">
<SearchBar searchBooks = {this.search}/>
<BookList booklist = {this.state.books}/>
</div>
);
}
}
export default App;
// Search Bar
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class SearchBar extends Component {
constructor(props) {
super(props);
this.state = { titleToSearch: 'harry potter' }
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(e) {
this.setState({ titleToSearch: e.target.value });
};
render() {
return (
<form>
<input
type="text"
name="booksInput"
placeholder="Enter book title"
value={this.state.titleToSearch}
onChange={this.handleInputChange}
/>
<button type="button" onClick={() => this.props.searchBooks(this.state.titleToSearch)}>Search</button>
</form>
);
}
}
export default SearchBar;
// BookList
import React, { Component } from 'react';
class BookList extends Component {
render() {
const books = this.props.booklist;
return (
<div className="table">
{books.map((book) => {
console.log(book.id);
return (
<div className="box" key={book.id}>
<div className="img"><img src="assets/default-placeholder.jpg" alt="" /></div>
<div className="title">{book.title}</div>
<div className="category">Sample Category</div>
<div className="description">{book.description}</div>
</div>
);
})}
</div>
);
}
}
export default BookList;
In the sample code you provided, you're not actually dynamically outputting categories.
You've hard coded 'Sample category' in there.
book.category
...is not actually in the dataset.
There are categories which seem to be available under:
<div className="category">{book.volumeInfo.categories[0]}</div>
although you'll want to check if the array has length, and probably map or join each item in array to string.
just to be clear: the issue with your other fields is also that they're children of "volumeInfo"

React API elements not displaying on page

I've been looking for about 2 hours into why I am not displaying any of the information to the page. I've console logged my response from a simple random quote api and it shows, Author: and Quote: in the console, however these are not appearing in my fields, All I am seeing is the button.
import React, { Component } from 'react';
import QuoteMachine from './Quotemachine';
const END_POINT = 'https://random-quote-
generator.herokuapp.com/api/quotes/random';
class App extends Component {
constructor(props) {
super(props);
this.state = {
quote: {
text: '',
author: ''
}
}
}
getQuote() {
fetch(END_POINT)
.then(response => response.json())
.then(response => {
this.setState = ({
quote: response
});
console.log(response);
})
}
componentDidMount() {
this.getQuote();
}
render() {
return (
<div className="App">
<div className="container">
<QuoteMachine quote= {this.state.quote} />
<button id="new-quote" className="primary-color-
background" onClick={() => this.getQuote()}>New quote</button>
</div>
</div>
);
}
}
export default App;
And then here is my Quotemachine.js
import React from 'react'
import PropTypes from 'prop-types';
const QuoteMachine = (props) => {
return (
<div className="quote-box">
<div className="text">
<span>{props.quote.text}</span>
</div>
<div className="author">
<span >{props.quote.author}</span>
</div>
</div>
);
};
QuoteMachine.propTypes = {
quote: PropTypes.object.isRequired
};
export default QuoteMachine;
It is only displaying the button, but the console.log shows
Object
author:
"Thomas Henry Huxley (1825-1895)"
quote:
"Try to learn something about everything and everything about something."
proto
:
Object
Install React Developer Tools plugin and check if your state is changing after the API call

can i pass a state value with the jsx code ?? in reactjs

Hello everybody I'm wondering if I can pass a state value from a component to other where I'm returning jsx code to be displayed for example I have 3 components.
1
import React, { Component } from 'react';
import Conteneur from './Conteneur';
class Header extends React.Component {
constructor(props) {
super(props);
this.state = { value: '' };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({ value: event.target.value });
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
<Conteneur values={this.state.value} />
</form>
);
}
}
export default Header;
2 app.js
import React, { Component } from 'react';
import Header from './Header';
import Conteneur from './Conteneur';
import './App.css';
class App extends Component {
render() {
return (
<div className="App" >
<br />
<Header />
<br />
<Conteneur />
</div>
);
}
}
export default App;
3 and finally
import React, { Component } from 'react';
const Conteneur = () => {
return (
<div className="tab"><span>ok test </span></div>
);
};
export default Conteneur;
I like to pass the state value of header that I have from the input to conteneur and then display in the box while I have some code all the examples that I saw online they are sending state like this:
class Dashboard extends Component {
...
...
render(){
return(
<Sidebar data={this.state.data1}/>
);
}
}
So can I do like this <Conteneur values={this.state.value} /> in the form ?
And I imported Conteneur.
i updated the code but the output is
Yes you can do, only one thing you are missing. Receive the props in the function parameters then render that in the ui.
Like this:
const Conteneur = (props) => {
return (
<div className="tab"><span>value: {props.value} </span></div>
);
};

this.props.createTask is not defined

I am following this tutorial React Tutorial
Here is the thing:
I am calling function createTask from create-todo.js;
the function is defined in app.js
app.js
import React from 'react';
import ToDosList from './todos-list';
import CreateToDoItem from './create-todo-item'
const todoitems=[
{
task: 'finish react todo tutorial',
isCompleted: false
},
{
task: 'eat lunch',
isCompleted: true
}
];
export default class App extends React.Component
{
constructor(props){
super(props)
this.state={
todoitems
};
}
render()
{
return(
<div>
<h1>React Demo App - ToDos </h1>
<CreateToDoItem createtask ={this.createTask.bind(this)}/>
<ToDosList
todoitems={this.state.todoitems}
/>
</div>
);
}
createTask(task)
{
//alert('called');
this.state.todoitems.push({
task,
isCompleted:false
});
this.setState({todoitems: this.state.todoitems});
}
}
create-todo.js
import React from 'react';
import App from './app';
export default class CreateToDoItem extends React.Component
{
render()
{
return(
<form onSubmit={this.handleCreate.bind(this)}>
<input type="text" placeholder="what do I need to do?" ref="createInput"/>
<button>Create</button>
</form>
);
}
handleCreate(event)
{
event.preventDefault();
//alert('called');
this.props.createTask(this.refs.createInput.value); //this throws error
}
}
I am absolutely new to React.js. I don't know how this works. Should the function be available to create-todo.js? The code is exactly how it is shown in the tutorial.
Reason is, you are passing the function in props by a different key and using inside child by a different key.
Actual function name: createTask
Passing in props by key: createtask
Using inside child by: createTask
so use this.props.createtask() instead of this.props.createTask()
Your prop is named "createtask". You should probably change your prop name to createTask (as opposed to changing references to this.props.createtask).
You could do like this:
import React from 'react';
import ToDosList from './todos-list';
import CreateToDoItem from './create-todo-item'
const items = [
{
task: 'finish react todo tutorial',
isCompleted: false
},
{
task: 'eat lunch',
isCompleted: true
}
];
export default class App extends React.Component {
state = {
todoitems: items,
taskItem: ''
}
handleChange = (e) => {
this.setState({
taskItem: e.target.value
})
}
handleCreate = () => {
e.preventDefault()
item = {
task: taskItem,
isCompleted: false // default value
}
this.setState({
todoitems: [...this.state.todoitems, item ]
})
}
render() {
return (
<div>
<h1>React Demo App - ToDos </h1>
<CreateToDoItem
handleChange={this.handleChange}
handleCreate={this.handleCreate}
taskItem={this.state.taskItem}
/>
<ToDosList todoitems={this.state.todoitems}
/>
</div>
);
}
}
Then your form will be:
import React from 'react';
import App from './app';
export const CreateToDoItem = (props) => (
<form onSubmit={props.handleCreate}>
<input type="text" placeholder="what do I need to do?"
onChange={props.handleChange}
value={props.taskItem} />
<button type='submit'>Create</button>
</form>
);
I hope it help you :)
Kindly,

Resources