Currently whenever I try to link to a nested route that renders a new element, I get the too much recursion error. For obvious reasons it keeps rerendering this component. Where does one put a nested route so it doesnt get rendered over and over again?
redirectAddSurvey(){
this.props.addSurvey("Titel Survey", "Survey beschrijving"); this.props.history.push(`/survey/${this.props.match.params.action}`);
}
render() {
return (
<div id="newSurveyButton">
<RaisedButton containerElement={ <Link to={`${this.props.match.url}/new`} />} label="Add new Survey" onClick={() => this.redirectAddSurvey()}></RaisedButton>
<Route path={`${this.props.match.url}/:action`} render={props => <Survey title="Helloworld" desc="HelloDesc" {...props} />} />
</div>
);
}
}
// Get apps state and pass it as props to SurveyList
// > whenever state changes, the SurveyList will automatically re-render
function mapStateToProps(state) {
return {
surveys: state.surveys,
};
}
Updated:
render() {
return (
<div id="newSurveyButton">
<RaisedButton label="Add new Survey" onClick={() => this.redirectAddSurvey()}></RaisedButton>
<Link to={`${this.props.match.url}/new`} />
<Route path={`survey/:action`} render={props => <Survey title="Helloworld" desc="HelloDesc" {...props} />} />
</div>
);
}
Related
I'm struggeling with making my Formik form work. Here a part of my code:
import { Formik, Form as FormikForm, Field } from "formik";
import {TextField} from "#mui/material";
<Formik
initialValues={{
name: "test",
}}
onSubmit={this.onSubmit}
>
{({ values,handleChange }) => (
<FormikForm>
<Field
component={TextField}
name="name"
label="Name"
fullWidth
></Field>
<Button
color="success"
variant="contained"
type="submit"
onClick={() => {
console.log(values);
}}
>
Erstellen
</Button>
</FormikForm>
)}
</Formik>
It seems like its having trouble connecting the values state to the Field value, since the initialValue isn't displayed in the names field. When i submit, it logs {name: 'test'} to console, no matter what i enter in the input field.
Edit 1:
I also have a very similar form that works. The only difference between the two that i can think of is: the working one is a .jsx while this one is .tsx. Dont know if that has anything to do with it.
According to the Field documentation you need to spread the field and pass it to the component like this:
import { Formik, Form as FormikForm, Field } from "formik";
import { Button, TextField } from "#mui/material";
const MuiTextField = ({ field, form, ...props }) => {
return <TextField {...field} {...props} />;
};
const MyComponent = () => {
return (
<Formik
initialValues={{
name: "test"
}}
onSubmit={(values) => {
console.log(values);
}}
>
{({ values, handleChange }) => (
<FormikForm>
<Field
component={MuiTextField}
name="name"
label="Name"
fullWidth
></Field>
<Button
color="success"
variant="contained"
type="submit"
onClick={() => {
console.log(values);
}}
>
Erstellen
</Button>
</FormikForm>
)}
</Formik>
);
};
export default MyComponent;
You can take a look at this sandbox for a live working example of this solution.
Like Ahmet pointed out, the problem seems to be that the field prop needs to be spread (see his answer). However i found, that using as instead of component works too and doesnt need spreading.
<Field
as={TextField}
name="name"
label="Name"
fullWidth
></Field>
I'm pretty new here to gatsby/programming and i was playing around with the gatsby. I have below issue and I would appreciate if you could let me know where does it goes wrong? Below is my code.
Problem 1: Why i can't return/access the {post1.categories.nodes.name} ? It shows nothing on my page.
Note that there was no problem for me to access {post.video.videoSource} so i guess my Graphql worked fine but when i tried with {post1.categories.nodes.name}, it was literally blank.
Any suggestions? Thank you very much.
const BlogIndex = ({
data,
pageContext: { nextPagePath, previousPagePath },
}) => {
const posts = data.allWpPost.nodes
if (!posts.length) {
return (
<Layout isHomePage>
<Seo title="All posts" />
<Bio />
<p>
No blog posts found. Add posts to your WordPress site and they'll
appear here!
</p>
</Layout>
)
}
return (
<Layout isHomePage>
<Seo title="All posts" />
{/* <Bio /> */}
<Grid container rowSpacing={5} column spacing={5}>
<Grid item xs={12} sm={3} md={3} lg={3}>
<Paper>
<ol style={{ listStyle: `none` }}>
{posts.map(post1 => {
return <li>{post1.categories.nodes.name}</li>
})}
</ol>
</Paper>
</Grid>
<Grid item xs={12} sm={9} md={9} lg={9}>
<Paper>
<ol style={{ listStyle: `none` }}>
{posts.map(post => {
const hasVideoUrl = post.video.videoSource
if (hasVideoUrl !== null) {
return (
<li key={post.uri}>
<article
className="post-list-item"
itemScope
itemType="http://schema.org/Article"
>
<header>
<small>{post.video.videoSource}</small>
<small>{post.video.videoUrl}</small>
{/* <ReactPlayer url={post.video.videoUrl} /> */}
</header>
</article>
</li>
)
} else {
return null
}
})}
</ol>
</Paper>
</Grid>
</Grid>
{previousPagePath && (
<>
<Link to={previousPagePath}>Previous page</Link>
<br />
</>
)}
{nextPagePath && <Link to={nextPagePath}>Next page</Link>}
</Layout>
)
}
export default BlogIndex
export const pageQuery = graphql`
query WordPressPostArchive($offset: Int!, $postsPerPage: Int!) {
allWpPost(
sort: { fields: [date], order: DESC }
limit: $postsPerPage
skip: $offset
) {
nodes {
excerpt
uri
date(formatString: "MMMM DD, YYYY")
title
video {
videoSource
videoUrl
}
categories {
nodes {
name
}
}
}
}
}
`
Problem 2 [Added 2 July 2022]:
<ul>
{wpPosts.map(wpPost => {
wpPost.tags.nodes.map(tag => {
console.log(tag.name)
if (tag.name === "Blog") {
return (
<div>
<li>{tag.title}</li>
</div>
)
}
})
})}
</ul>
const data = useStaticQuery(
graphql`
query {
allWpPost(sort: { fields: date, order: DESC }, limit: 10) {
nodes {
excerpt
slug
uri
video {
videoTitle
videoUrl
}
title
date(formatString: "MMMM DD, YYYY")
tags {
nodes {
name
}
}
}
}
}
`
)
const wpPosts = data.allWpPost.nodes
Problem 1: Why i can't return/access the {post1.categories.nodes.name}
? It shows nothing on my page.
nodes (in post1.categories.nodes.name) is likely to be an array, so you will need to loop through it or access a specific position:
return <li>{post1.categories.nodes[0].name}</li>
Depending on your data structure you'll need to loop or just access to the first position. Without knowing your data it's difficult to guess.
I am trying create a simple crud system with react redux and form-redux.
The code below but does not work and gives error.
First I created an action for update and then created a reducer for that.
And then created component to use the action.
Let me know how to get this to work.
//-------------action--------------
export const EDIT_POST = 'EDIT_POST';
export const editPost = (id) => {
const request = axios.put(`${BOOK_URL}/books/${id}`);
return {
type: EDIT_POST,
payload: id,
}
};
//---------------- reducer-----------------
case EDIT_POST: {
return {...state, post: action.payload.data}
}
//----------------route--------------
<Route path='/posts/edit/:id' component={PostEdit}/>
//-------------------PostEdit---------------
class PostEdit extends Component {
componentDidMount = () => {
this.props.editPost(this.props.match.params.id);
console.log(this.props.editPost(this.props.match.params.id));
};
renderField = field => {
const {meta: {touched, error}} = field;
const className = `form-group ${touched && error ? 'has-danger' : ''}`;
return (
<div className='has-danger'>
<label>{field.label}</label>
<input type="text" {...field.input} className="form-control"/>
<div className="text-help">
{touched ? error : ''}
</div>
</div>
);
};
render() {
const {handleSubmit} = this.props;
return (
<form onSubmit={handleSubmit(this.onSubmitForm)}>
<Field name="title" label="Title" component={this.renderField}/>
<Field name="author" label="Author" component={this.renderField}/>
<Field name="description" label="Description" component={this.renderField}/>
<Field name="publicationDate" label="PublicationDate" component={this.renderField}/>
<button type='submit' className="btn btn-primary">Submit</button>
<Link to='/' className='btn btn-danger'>Cancel</Link>
</form>
);
}
}
export default reduxForm({
form :'updateForm'
})(connect(null, {editPost})(PostEdit));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
Could you tell what error you are getting?
You have to change your action like
export const fetchPosts = () => {
return (dispatch) => {
axios.get(`${BOOK_URL}/books`).then((response) => {
return dispatch({
type: FETCH_POSTS,
payload: // your response here
});
})
}
}
I have a redux-form with a react-select. The expected behaviour is that, as I type in the select field, I call the redux action (by using OnInputChange). But I don't know how to call the action. The line that calls the action is commented in the snippet below, because it fails (this.props.getArtistSearch(value)). Any ideas of how to properly call the action as user types in?
class FormApplication extends React.Component {
submit(values) {
this.props.submitForm(values)
}
getArtist(value){
//this.props.getArtistSearch(value) --> props is undefined
console.log(value)
}
render() {
const { handleSubmit } = this.props
return (
<form className='content text padding-top-0' onSubmit={handleSubmit(this.submit.bind(this))}>
<div className='row adjust-form-row'>
<div className='col-md-6 last-lineup'>
<div className='row adjust-form-row'>
<div className='col-md-6'>
<div className='form-group'>
<Field
name='dl_artistname'
options={this.props.gap.artistSearch}
component={props => (
<Select
{...props}
name={props.name}
onInputChange={this.getArtist}
onChange={(value) => {
this.props.requestArtistInstance({id: value.dl_artistid })
return props.input.onChange(value != null ? value.dl_artistid : null)}
}
onBlur={() => props.input.onBlur(props.input.value)}
options={props.options}
//loadOptions={getOptions}
clearable={false}
cache={false}
backspaceRemoves={false}
valueKey='dl_artistid'
labelKey='dl_name'
value={props.input.value || ''}
isLoading={false}
disabled={false}
/>
)}
/>
</div>
</div>
</div>
</div>
</div>
</form>
)
}
}
const mapDispatchToProps = dispatch => ({
getArtistSearch: (text) => {
dispatch(getArtistSearch(text))
},
submitForm: (values) => {
dispatch(submitForm(values))
}
})
Going through your code, I noticed that the custom method you defined, getArtist was not bound to your React context so props will be undefined. Two possible approaches for this are:
1) bind it in the constructor method
constructor(){
super();
this.getArtist = this.getArtist.bind(this);
}
2) Alternatively, bind it in the Select component(Not ideal tho')
onInputChange={this.getArtist.bind(this)}
I'm trying to use react-router with a server in Go.
I did some tests but I can not do what I want.
My react components :
var App = React.createClass({
render: function(){
return (
<div>
<h2>App</h2>
<li><Link to="/page1">Page 1</Link></li>
<li><Link to="/page2">Page 2</Link></li>
</div>
)
}
})
var Page1 = React.createClass({
render: function(){
return (
<div>
<h2>Page 1</h2>
<li><Link to="/page2">Page 2</Link></li>
</div>
)
}
})
var Page2 = React.createClass({
render: function(){
return (
<div>
<h2>Page 2</h2>
<li><Link to="/page1">Page 1</Link></li>
</div>
)
}
})
My react routing :
ReactDOM.render((<Router history={browserHistory}>
<Route path="/" component={App}>
<Route path="page1" component={Page1} />
<Route path="page2" component={Page2} />
</Route>
</Router>), document.getElementById('app'))
my go server :
func Render(c web.C, w http.ResponseWriter, r *http.Request) {
RenderHTMLPage(w, "index.html")
}
func main() {
goji.Get("/page1", Render)
goji.Get("/page2", Render)
goji.Get("/", Render)
goji.Serve()
}
My problem is when i click on Link in 'App' Component, for example :
<li><Link to="/page1">Page 1</Link></li>
url changes like that
http://localhost:8000/page1
But actual component is already App and not Page1, so url changes but not component.
And if i load directly url, i have the same result.
Does anyone help me ?
Thank's :)
This isn't a go question, but a react question, you need to render the App component's children in order for the other two components to display, a la this code snippet taken from the docs for React Router (https://github.com/reactjs/react-router/blob/master/docs/API.md#props-2):
const routes = (
<Route component={App}>
<Route path="groups" component={Groups} />
<Route path="users" component={Users} />
</Route>
)
class App extends React.Component {
render () {
return (
<div>
{/* this will be either <Users> or <Groups> */}
{this.props.children}
</div>
)
}
}