[英]Returns object / JSON value instead of full value, React, Graphql, Nextjs
相反,我只想訪問我的帖子頁面上的標簽輸出USA
我可以訪問post.countries ? countries.label : ""
post.countries ? countries.label : ""
on create-post,一旦我提交,我就會在控制台視圖截圖中看到完整的 JSON
對此的任何幫助都非常感謝
如果這是重復的,請道歉
// pages/my-posts.js
import { useState, useEffect } from 'react'
import Link from 'next/link'
import { API, Auth } from 'aws-amplify'
import { postsByUsername } from '../graphql/queries'
import { deletePost as deletePostMutation } from '../graphql/mutations'
import MySelect from '../components/Autocomplete'
const initialState = { title: '', content: '', category: '', countries: '', createdAt: new Date().toISOString() }
export default function MyPosts() {
const [posts, setPosts] = useState([])
const [post, setPost, state] = useState(initialState)
const { title, content, category, countries, createdAt } = post
const [noOfElement, setnoOfElement] = useState(4)
const slice = posts.slice(0, noOfElement)
const loadMore = () => {
setnoOfElement(noOfElement + noOfElement)
}
useEffect(() => {
fetchPosts()
}, [])
async function fetchPosts() {
const { username } = await Auth.currentAuthenticatedUser()
const postData = await API.graphql({
query: postsByUsername,
variables: { username }
})
setPosts(postData.data.postsByUsername.items);
console.log('console', postData.data.postsByUsername.items);
}
async function deletePost(id) {
await API.graphql({
query: deletePostMutation,
variables: { input: { id } },
authMode: "AMAZON_COGNITO_USER_POOLS"
})
fetchPosts()
}
return (
<div>
<h1 className="text-3xl font-semibold tracking-wide mt-6 mb-2">My Posts</h1>
{
slice.map((post, index) => (
<div key={index} className="border-b border-gray-300 mt-8 pb-4">
<h2 className="text-xl font-semibold">Title: {post.title}</h2>
<p className="text-gray-500 mt-2 mb-2">Author: {post.username}</p>
<h2 className="text-xl font-semibold">Author's Category: {post.category}</h2>
<h2 className="text-xl font-semibold">Author's Country: {post.countries}</h2>
<time dateTime={post.createdAt}>
{new Date(post.createdAt).toDateString()}</time>
<Link href={`/edit-post/${post.id}`}><a className="text-sm mr-4 text-blue-500">Edit Post</a></Link>
<Link href={`/posts/${post.id}`}><a className="text-sm mr-4 text-blue-500">View Post</a></Link>
<button
className="text-sm mr-4 text-red-500"
onClick={() => deletePost(post.id)}
>Delete Post</button>
</div>
))
}
<button type="button"
onClick={() => loadMore()}
>
Load more posts
</button>
</div>
)
}
創建 post.js
import { withAuthenticator } from '@aws-amplify/ui-react'
import { useState, useRef } from 'react' // new
import { API, Storage } from 'aws-amplify'
import { v4 as uuid } from 'uuid'
import { useRouter } from 'next/router'
import SimpleMDE from "react-simplemde-editor"
import "easymde/dist/easymde.min.css"
import { createPost } from '../graphql/mutations'
import MySelect from '../components/Autocomplete'
const initialState = { title: '', content: '', category: '', countries: '', createdAt: new Date().toISOString() }
function CreatePost() {
const [post, setPost, state] = useState(initialState)
const hiddenFileInput = useRef(null);
const { title, content, category, countries, createdAt } = post
const router = useRouter()
function onChange(e) {
setPost(() => ({ ...post, [e.target.name]: e.target.value }))
}
async function createNewPost() {
if (!title || !content || !category || !countries || !createdAt) return
const id = uuid()
post.id = id
await API.graphql({
query: createPost,
variables: { input: post },
authMode: "AMAZON_COGNITO_USER_POOLS"
})
router.push(`/posts/${id}`)
}
state = {
selected: null
};
console.log('countries', post.countries ? countries.label : "")
return (
<div>
<h1 className="text-3xl font-semibold tracking-wide mt-6">Create new post</h1>
<input
onChange={onChange}
name="title"
placeholder="Title"
value={post.title}
className="border-b pb-2 text-lg my-4 focus:outline-none w-full font-light text-gray-500 placeholder-gray-500 y-2"
/>
<input
onChange={onChange}
name="category"
placeholder="Author Category"
value={post.category}
className="border-b pb-2 text-lg my-4 focus:outline-none w-full font-light text-gray-500 placeholder-gray-500 y-2"
/>
<input
onChange={onChange}
name="createdAt"
placeholder="Time created"
value={post.createdAt}
className="invisible"
/>
<MySelect
options={options}
name="countries"
onChange={onChange => setPost({ ...post, countries: onChange })}
value={post.countries}
/>
<div>label: {post.countries ? countries.label : ""}</div>
<SimpleMDE value={post.content} onChange={value => setPost({ ...post, content: value })} />
<button
type="button"
className="mb-4 bg-blue-600 text-white font-semibold px-8 py-2 rounded-lg"
onClick={createNewPost}
>Save Article</button>
</div>
)
}
const options = [
{
value: "1",
label: "Australia"
},
{
value: "2",
label: "New Zealand"
},
{
value: "3",
label: "USA"
},
{
value: "4",
label: "Italy"
}
];
export default withAuthenticator(CreatePost)
type Post @model
@key(name: "postsByUsername", fields: ["username"], queryField: "postsByUsername")
@auth(rules: [
{ allow: owner, ownerField: "username" },
{ allow: public, operations: [read] }
]) {
id: ID!
title: String!
category: String!
countries: String!
createdAt: String!
content: String!
username: String
}
onChange={onChange => setPost({ ...post, countries: onChange.value })}
.value
返回值不是對象
import { withAuthenticator } from '@aws-amplify/ui-react'
import { useState, useRef } from 'react'
import { API, Storage } from 'aws-amplify'
import { v4 as uuid } from 'uuid'
import { useRouter } from 'next/router'
import SimpleMDE from "react-simplemde-editor"
import "easymde/dist/easymde.min.css"
import { createPost } from '../graphql/mutations'
import MySelect from '../components/Autocomplete'
// import MyCategorySelect from '../components/Category'
import { useForm } from "react-hook-form";
import { ErrorMessage } from '@hookform/error-message';
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
const initialState = { title: '', content: '', category: '', countries: '', select: '', date: '', createdAt: new Date().toISOString()}
function CreatePost() {
const [startDate, setStartDate] = useState(new Date());
const { register, handleSubmit, formState: { errors } } = useForm();
const onSubmit = data => console.log(data);
const [post, setPost, state] = useState(initialState)
const hiddenFileInput = useRef(null);
const { title, content, category, countries, select, date, createdAt } = post
const router = useRouter()
function onChange(e) {
setPost(() => ({ ...post, [e.target.name]: e.target.value }))
}
console.log('setPost', post.countries ? countries.label : "")
async function createNewPost() {
//if ( !title || !content || !category || !countries || !select || !date || !createdAt ) return
const id = uuid()
post.id = id
await API.graphql({
query: createPost,
variables: { input: post },
authMode: "AMAZON_COGNITO_USER_POOLS"
})
router.push(`/posts/${id}`)
}
return (
<form onSubmit={handleSubmit(onSubmit)} autoComplete="off"
noValidate>
<div>
<h1 className="text-3xl font-semibold tracking-wide mt-6">Create New Article</h1>
<p className="mt-6">Enter Title: </p>
<input
aria-invalid={errors.title ? "true" : "false"}
{...register('title', { required: true })}
onChange={onChange}
name="title"
placeholder="Title"
value={post.title}
className="border-b pb-2 text-lg my-4 focus:outline-none w-full font-light text-gray-500 placeholder-gray-500 y-2"
/>
{errors.title && (
<span role="alert" className="mb-4 mt-4 alert">
This field is required
</span>
)}
<p>Enter Author's Category: </p>
<input
aria-invalid={errors.category ? "true" : "false"}
{...register('category', { required: true })}
onChange={onChange}
name="category"
placeholder="Author Category"
value={post.category}
className="mb-4 mt-4 border-b pb-2 text-lg my-4 focus:outline-none w-full font-light text-gray-500 placeholder-gray-500 y-2"
/>
{errors.category && (
<span role="alert" className=" alert">
This field is required
</span>
)}
<p className="mb-2 mt-2" >Select Created Date: </p>
<DatePicker
// onChange={(date) => setStartDate(date)}
aria-invalid={errors.date ? "true" : "false"}
{...register('date', { required: true })}
selected={post.date}
onChange={(date) => setPost({...post, date})}
name="date"
placeholder="Created date"autoComplete
//value={post.date}
className="visible focus:outline-black outline-black"
/>
{errors.date && (
<span role="alert" className="mb-12 mt-12 alert">
This field is required
</span>
)}
<div className="mb-2 mt-2">
<p>Select Author's Country: </p>
<MySelect
aria-invalid={errors.countries ? "true" : "false"}
{...register('countries', { required: true })}
options={options}
name="countries"
onChange={onChange => setPost({ ...post, countries: onChange.value })}
value= {post.countries}
className="m-6"
placeholder="Countries Select..."
/>
</div>
<div className="ml-6 alert">
{errors.countries && (
<span role="alert" className="mb-12 mt-12 alert">
This field is required
</span>
)}
</div>
<div className="mb-2 mt-2">
<p>Select Blog's Category: </p>
<MySelect
aria-invalid={errors.select ? "true" : "false"}
{...register('select', { required: true })}
options={selectCategoryOptions}
name="select"
onChange={onChange => setPost({ ...post, select: onChange.label})}
value= {post.select}
className="m-6"
placeholder="select Select..."
/>
</div>
<div className="ml-6 alert">
{errors.select && (
<span role="alert" className="mb-12 mt-12 alert">
This field is required
</span>
)}
</div>
<div className="mb-2 mt-2">
</div>
<p className="mt-8" >Enter Blog Content: </p>
<SimpleMDE
aria-invalid={errors.content ? "true" : "false"}
{...register('content', { required: true })}
value={post.content}
onChange={value => setPost({ ...post, content: value })}
/>
{errors.content && (
<span role="alert" className="mb-4 mt-4 alert">
This field is required
<br/>
<p className="alert font-semibold">
Please check all fields are filled in & wait 3 seconds before refreshing the page
</p>
</span>
)}
<input
onChange={onChange}
name="createdAt"
placeholder="Time created"
value={post.createdAt}
className="invisible"
/>
<br/>
<button
type="submit"
className="mb-4 mt-4 bg-blue-600 text-white font-semibold px-8 py-2 rounded-lg"
onClick={createNewPost}
>Save Article</button>
</div>
</form>
)
}
const selectCategoryOptions = [
{
label: "Sport"
},
{
label: "News"
},
{
label: "Weather"
},
{
label: "Other"
}
];
const options = [
{ label: 'Africa', value: 'Africa' },
{ label: 'USA', value: 'USA' },
{ label: 'Asia', value: 'Asia' },
{ label: 'Europe', value: 'Europe' },
{ label: 'Oceania', value: 'Oceania' },
]
export default withAuthenticator(CreatePost)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.