Building a React Markdown Previewer - reactjs

I´m having troubles making the Input from the text area go to the Marked interpreter (getting a TypeError: Cannot read property 'value' of null). Any ideas on how to fix it?
Text area input:
import React, { Component } from 'react';
import './App.css';
import marked from "marked";
import MarkdownExample from "./previewer";
class Editor extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 'Some markdown text.'
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
createMarkup()
{
return {__html: marked(this.state.value)};
}
render() {
return (
<div>
<textarea value={this.state.value} onChange={this.handleChange}/>
<MarkdownExample />
</div>
);
}
}
Previewer:
import React, { Component } from 'react';
import './App.css';
import marked from "marked";
class MarkdownExample extends React.Component {
getMarkdownText(props) {
var rawMarkup = marked(this.state.value, {sanitize: true});
return { __html: rawMarkup };
}
render() {
return <div dangerouslySetInnerHTML={this.state.value.getMarkdownText()} />
}
}
export default MarkdownExample;

You cannot access state directly from parent, but you can pass the prop to the child
import React, { Component } from 'react';
import './App.css';
import marked from "marked";
import MarkdownExample from "./previewer";
class Editor extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 'Some markdown text.'
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
createMarkup()
{
return {__html: marked(this.state.value)};
}
render() {
return (
<div>
<textarea value={this.state.value} onChange={this.handleChange}/>
<MarkdownExample parentValue={this.state.value}/>
</div>
);
}
}
Previewers:
import React, { Component } from 'react';
import './App.css';
import marked from "marked";
class MarkdownExample extends React.Component {
getMarkdownText() {
var rawMarkup = marked(this.props.parentValue, {sanitize: true});
return { __html: rawMarkup };
}
render() {
return <div dangerouslySetInnerHTML={this.getMarkdownText()} />
}
}
export default MarkdownExample;

Related

How to call react function from console?

I want use consloe to call function like js, but consloe display "Uncaught ReferenceError: isDebug is not defined at :1:1".
SalesKpi.tsx
import * as React from 'react';
import styles from './SalesKpi.module.scss';
import './SalesKpi.css';
import { ISalesKpiProps } from './ISalesKpiProps';
import { escape } from '#microsoft/sp-lodash-subset';
import 'bootstrap/dist/css/bootstrap.css';
import $ from 'jquery';
export default class SalesKpi extends React.Component<ISalesKpiProps, {show: boolean;}> {
public constructor(props) {
super(props);
this.state = {
show: false
}
}
public debug(){
this.setState({show: true})
}
public render(): React.ReactElement<ISalesKpiProps> {
return (
<div className="row">
{this.state.show &&
<div className="col">
.................
</div>
}
</div>
)
}

TypeError: this.props.changeUser is not a function

I am new in React Js and want to call the parent method from the child method.
There is a class login.jsx when someone clicks on submits button then a method changeUser in FirstPage.jsx should be invoked but when I try the online solution I am getting same error again and again that this.props.changeUser is not a function.
Login.jsx (child class)
import React, { Component } from 'react';
class Login extends Component {
constructor(props){
super(props);
this.state ={
user : null
}
this.onNameChange = this.onNameChange.bind(this);
this.onHandleClick = this.onHandleClick.bind(this);
}
onNameChange = (event)=>{
this.setState({
user:event.target.value
})
}
onHandleClick=(event)=>{
event.preventDefault();
this.props.changeUser("hello");
}
render() {
return (
<form>
<h3>Sign In</h3>
<div>
<label>User Name</label>
<input type="text" name="userId" placeholder="Enter User name" onChange ={this.onNameChange}/>
</div>
<button className="btn btn-primary btn-block" onClick={this.onHandleClick}>Submit</button>
</form>
);
}
}
export default Login;
FirstPage.jsx (parent class)
import React, { Component } from 'react';
import Login from './Login';
class Firstpage extends Component {
constructor(props){
super(props);
this.state=
{
user:null
}
this.changeUser = this.changeUser.bind(this)
}
changeUser =(x)=>{
console.log(x)
}
render() {
return (
<div>
<Login changeUser ={this.changeUser}/>
</div>
);
}
}
export default Firstpage;import React, { Component } from 'react';
import Login from './Login';
class Firstpage extends Component {
constructor(props){
super(props);
this.state=
{
user:null
}
this.changeUser = this.changeUser.bind(this)
}
changeUser =(x)=>{
console.log(x)
}
render() {
return (
<div>
<Login changeUser ={this.changeUser}/>
</div>
);
}
}
export default Firstpage;
I am getting an error that TypeError: this.props.changeUser is not a function
Please help me.
try to avoid using a lambda expression within you class component. Just create a simple member function:
import React, { Component } from 'react';
import Login from './Login';
class Firstpage extends Component {
constructor(props){
super(props);
this.state=
{
user:null
}
this.changeUser = this.changeUser.bind(this)
}
changeUser(x) // Try to declare this as member function
{
console.log(x)
}
render() {
return (
<div>
<Login changeUser ={this.changeUser}/>
</div>
);
}
}
export default Firstpage
You are making a mistake here while binding , inside constructor
//WRONG
this.onNameChange = this.onNameChange.bind(this);
this.onHandleClick = this.onHandleClick.bind(this);
//RIGHT
this.onNameChange = onNameChange.bind(this);
this.onHandleClick = onHandleClick.bind(this);
CODE:
constructor(props){
super(props);
this.state ={
user : null
}
this.onNameChange = onNameChange.bind(this);
this.onHandleClick = onHandleClick.bind(this);
}

React: Props are not being passed to children

So I have this parent which clone and injects props Login to the children:
import React, { Component } from 'react';
import { Container } from 'reactstrap';
import { NavMenu } from '../navigations/NavMenu';
import { Login } from './account/Login';
export class Layout extends Component {
static displayName = Layout.name;
render() {
const loginForm = new Login();
const childrenWithProps = React.Children.map(this.props.children, child => {
if (React.isValidElement(child)) {
return React.cloneElement(child, { loginForm: loginForm });
}
return child;
});
return (
<div>
{loginForm.render()}
<NavMenu />
<Container>
{childrenWithProps}
</Container>
</div>
);
}
}
This is one of the children:
import React, { Component } from 'react';
import { http } from '../../helpers/Http';
export class FetchData extends Component {
static displayName = FetchData.name;
constructor(props) {
super(props);
this.state = { forecasts: [], loading: true };
let x = this.props.loginForm; <-- THIS IS UNDEFINED
}
.......
}
The this.props.loginForm is undefined. How can I inject props correctly?
EDIT
This is the Login component:
import React, { Component } from 'react';
import './Login.css';
export class Login extends Component {
constructor(props) {
super(props);
this.state = { show: false };
this.login = this.login.bind(this);
this.showLogin = this.showLogin.bind(this);
}
showLogin() {
this.setState({
show: true
});
}
login() {
}
render() {
return (
<form className={this.state.show ? "login-form " : "login-form hide"} onSubmit={this.login()}>
<h1>Login</h1>
<div className="form-group">
<input required type="text" placeholder="Email" />
<input required type="password" placeholder="Password" />
</div>
<button type="submit" className="btn btn-primary">Login</button>
</form>
);
}
}
I want to call showLogin() from FetchData. If the user is not authorized when fetching the data, I want to show the login modal.

Passing data to another after receiving data from call back in react js

I am a beginner in react js so what I want to do it is :
I want to pass the quizData array to another component , data in quizData is set from a callback function which is submitForm function . But when I try to print the prop in another Component(QuizScreen)
it prints 1 as the value console .
Can anybody Please suggest . Am I doing something wrong with the design pattern ?
Thanks in Advance.
import React from 'react';
import logo from './logo.svg';
import './App.css';
import QuizForm from './QuizForm.js'
import QuizScreen from './QuizScreen';
class App extends React.Component{
state = {
isSubmitted : false,
quizData : [],
}
submitForm = (data) =>{
this.setState({isSubmitted : true,
quizData : this.state.quizData.push(data)
})
console.log("Value of quizData is "+ JSON.stringify(this.state.quizData))
}
render() {
return (
<div className="App">
<div className= "container">
{(!this.state.isSubmitted) ? <QuizForm isFormSubmit= {this.submitForm} /> : <QuizScreen details={this.state.quizData}/>}
</div>
</div>
);
}
}
export default App;
import React from 'react'
class QuizScreen extends React.Component {`enter code here`
constructor(props)
{
super(props)
console.log("Props is "+JSON.stringify(props.details))
}
render(){
return(
<div className= "App">
</div>
)
}
}
export default QuizScreen;
import React , {Component} from 'react'
import FileUpload from './FileUpload';
import QuizScreen from './QuizScreen.js'
import './QuizForm.css'
import InputTextField from './InputTextField';
import fields from './Fields.js';
class QuizForm extends Component {
constructor(props) {
super(props);
this.state = {
value: '',
fileData : [],
negativeMarking : 0,
quizName : '',
category :'',
weightage : 0,
quizTime: '',
isSubmitted: false
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
myfile = (fileUploadData) =>{
console.log("Hello from myfile"+JSON.stringify(fileUploadData));
this.setState({fileData : fileUploadData})
}
handleChange(event) {
console.log("My values are "+event.target.name)
const value = event.target.value;
this.setState({[event.target.name] :value })
}
handleSubmit(event) {
alert('QuizName is '+event.target.quizName.value)
event.preventDefault();
this.setState({isSubmitted : true})
this.props.isFormSubmit(this.state)
}
render() {
return (
<div className="form-style-6">
<h1>Create Quiz</h1>
<form onSubmit={this.handleSubmit}>
{fields.map(form =>{
return(
<InputTextField
type={form.type}
name={form.name}
_handleChange={this.handleChange}
placeholder= {form.placeholder}
key={form.placeholder}
/>
);
} )}
<FileUpload onFileUpload = {this.myfile}/>
<input type="submit" value="Submit"/>
</form>
</div>
);
}
}
export default QuizForm;
You have to refer the current component scope by putting this keyword when you want to access props. Plus, print it on your console by calling it inside a componentDidMount().
import React from 'react';
class QuizScreen extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
console.log('Props is ' + JSON.stringify(this.props.details)); //<-- Here you have to put `this` keyword.
}
render() {
return <div className="App"></div>;
}
}
export default QuizScreen;
import React , {Component} from 'react'
import FileUpload from './FileUpload';
import QuizScreen from './QuizScreen.js'
import './QuizForm.css'
import InputTextField from './InputTextField';
import fields from './Fields.js';
class QuizForm extends Component {
constructor(props) {
super(props);
this.state = {
value: '',
fileData : [],
negativeMarking : 0,
quizName : '',
category :'',
weightage : 0,
quizTime: '',
isSubmitted: false
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
myfile = (fileUploadData) =>{
console.log("Hello from myfile"+JSON.stringify(fileUploadData));
this.setState({fileData : fileUploadData})
}
handleChange(event) {
console.log("My values are "+event.target.name)
const value = event.target.value;
this.setState({[event.target.name] :value })
}
handleSubmit(event) {
alert('QuizName is '+event.target.quizName.value)
event.preventDefault();
this.setState({isSubmitted : true})
this.props.isFormSubmit(this.state)
}
render() {
return (
<div className="form-style-6">
<h1>Create Quiz</h1>
<form onSubmit={this.handleSubmit}>
{fields.map(form =>{
return(
<InputTextField
type={form.type}
name={form.name}
_handleChange={this.handleChange}
placeholder= {form.placeholder}
key={form.placeholder}
/>
);
} )}
<FileUpload onFileUpload = {this.myfile}/>
<input type="submit" value="Submit"/>
</form>
</div>
);
}
}
export default QuizForm;

How to make Button work on Input (REACT)

I would like to have, an Add button. The following is the React.js code that I thought is one way of implement the logic that I want, but unfortunately it's doesn't work.
my getting this Error:
bundle.js:47 Uncaught Error: Cannot find module "./src/index.js"
at webpackMissingModule at Object.<anonymous>
at __webpack_require__
How do I solve this problem?
import React from "react"
import ReactDOM from "react-dom"
import SearchBar from "./components/search_bar"
const API_KEY = "TheRealAPIKeyWouldGoHere"
const App = () => {
handleChange(value){
this.setState({
value: event.target.value
});
}
return ( <div>
<SearchBar onChange={this.handleChange}/>
</div>
)
}
ReactDOM.render(<App />, document.querySelector(".container"))
This is my component. I have assigned Button to input but i can't figure out how to make it work.
import React, { Component } from "react"
class SearchBar extends Component {
constructor(props){
super(props)
this.state = {term: ""}
}
handleChange(evt){
this.props.onChange(value);
}
render () {
return <div>
<button onClick={this.handleChange}>Search</button>
<input ref="inputName" onChange= { event => console.log(event.target.value)} />
</div>
}
}
export default SearchBar
In your component:
import React, { Component } from "react"
class SearchBar extends Component {
constructor(props) {
super(props)
this.state = { term: '' }
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange(event) {
this.setState({ value: event.target.term })
}
handleSubmit(event) {
console.log(event.target.value)
event.preventDefault()
}
render() {
return (
<div>
<button onClick={this.handleSubmit}>Search</button>
<input
type="text"
value={this.state.term}
onClick={this.handleChange}
/>
</div>
)
}
}
export default SearchBar

Resources