惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
Google Developers Blog
S
Schneier on Security
The Hacker News
The Hacker News
P
Proofpoint News Feed
Spread Privacy
Spread Privacy
L
LINUX DO - 热门话题
L
Lohrmann on Cybersecurity
I
Intezer
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Schneier on Security
Schneier on Security
Security Latest
Security Latest
AWS News Blog
AWS News Blog
B
Blog RSS Feed
Microsoft Security Blog
Microsoft Security Blog
有赞技术团队
有赞技术团队
博客园 - 叶小钗
The Last Watchdog
The Last Watchdog
O
OpenAI News
月光博客
月光博客
Hacker News: Ask HN
Hacker News: Ask HN
阮一峰的网络日志
阮一峰的网络日志
S
Security @ Cisco Blogs
Google Online Security Blog
Google Online Security Blog
云风的 BLOG
云风的 BLOG
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Latest news
Latest news
P
Palo Alto Networks Blog
Last Week in AI
Last Week in AI
M
MIT News - Artificial intelligence
Google DeepMind News
Google DeepMind News
P
Proofpoint News Feed
C
CERT Recently Published Vulnerability Notes
Apple Machine Learning Research
Apple Machine Learning Research
U
Unit 42
PCI Perspectives
PCI Perspectives
博客园 - 聂微东
SecWiki News
SecWiki News
宝玉的分享
宝玉的分享
Forbes - Security
Forbes - Security
H
Heimdal Security Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Hugging Face - Blog
Hugging Face - Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
T
Troy Hunt's Blog
博客园 - 三生石上(FineUI控件)
Application and Cybersecurity Blog
Application and Cybersecurity Blog
罗磊的独立博客
WordPress大学
WordPress大学
D
Darknet – Hacking Tools, Hacker News & Cyber Security

Kent C. Dodds Blog

Implementing Hybrid Semantic + Lexical Search Simplifying Containers with Cloudflare Sandboxes Migrating to Workspaces and Nx Offloading FFmpeg with Cloudflare Building Semantic Search on my Content Helping YOU ask ME questions with AI How I used Cursor to Migrate Frameworks The Dow's Start on the Covenant Path 2025 in Review The next chapter: EpicAI.pro AI is taking your job How I increased my visibility Launching Epic Web 2023 in Review Stop Being a Junior RSC with Dan Abramov and Joe Savona Live Stream Fixing a Memory Leak in a Production Node.js App 2022 in Review My Car Accident I Migrated from a Postgres Cluster to Distributed SQLite with LiteFS I'm building EpicWeb.dev A review of my time at Remix Remix: The Yang to React's Yin How I help you build better websites Why I Love Remix The State Initializer Pattern How to React ⚛️ Get a catch block error message with TypeScript Building an awesome image loading experience How Remix makes CSS clashes predictable Introducing the new kentcdodds.com How I built a modern website in 2021 How to use React Context effectively Static vs Unit vs Integration vs E2E Testing for Frontend Apps The Testing Trophy and Testing Classifications Array reduce vs chaining vs for loop Don't Solve Problems, Eliminate Them Super Simple Start to Remix Super Simple Start to ESModules in Node.js JavaScript Pass By Value Function Parameters How to write a Constrained Identity Function (CIF) in TypeScript How to optimize your context value How to write a React Component in TypeScript TypeScript Function Syntaxes Listify a JavaScript Array Build vs Buy: Component Libraries edition Using fetch with TypeScript Wrapping React.useState with TypeScript Define function overload types with TypeScript 2020 in Review Business and Engineering alignment Hi, thanks for reaching out to me 👋 useEffect vs useLayoutEffect Super simple start to Firebase functions Super simple start to Netlify functions Super Simple Start to css variables Favor Progress Over Pride in Open Source Testing Implementation Details How getting into Open Source has been awesome for me useState lazy initialization and function updates Use ternaries rather than && in JSX Application State Management with React Use react-error-boundary to handle errors in React JavaScript to Know for React How I structure Express apps What open source project should I contribute to? When I follow TDD AHA Programming 💡 How I Record Educational Videos Should I write a test or fix a bug? Stop mocking fetch Intentional Career Building Improve test error messages of your abstractions Tracing user interactions with React Eliminate an entire category of bugs with a few simple tools Common mistakes with React Testing Library Super Simple Start to React Stop using client-side route redirects The State Reducer Pattern with React Hooks Function forms Replace axios with a simple custom fetch wrapper How to test custom React hooks React Production Performance Monitoring Should I useState or useReducer? Stop using isLoading booleans Make Your Test Fail Make your own DevTools An Argument for Automation Fix the "not wrapped in act(...)" warning Super Simple Start to ESModules in the Browser Implementing a simple state machine library in JavaScript 2010s Decade in Review Why users care about how you write code Why I avoid nesting closures Don't call a React function component Why your team needs TestingJavaScript.com Inversion of Control Understanding React's key prop How to Enable React Concurrent Mode Profile a React App for Performance
React Fundamentals: Props vs State
2019-07-08 · via Kent C. Dodds Blog

Let's compare props and state. Here's a definition of each:

  • "props" (short for "properties") is an object of arbitrary inputs a React function component accepts as the first argument.
  • "state" is data that changes over the lifetime of a specific instance of a React component.

Let's dive into each.

Props

Think of props as arguments to a function. React components are functions which return JSX (or more generally something that's renderable like React elements, null, a string, etc.). Typically when you have a piece of code that you would like to reuse, you can place that code into a function and any dynamic values that code used before can be accepted as arguments (for example const five = 2 + 3 could be extracted to a function and accept arguments like so const five = add(2, 3)).

The same is true of a piece of JSX, except instead of calling it like a normal function (add(2, 3)) you use JSX syntax (<Add n1={2} n2={3} />). The "attributes" supplied in the JSX are what are called props and they are placed together in a single object and passed to the Add component function as the first argument like so:

function Add(props) {
	return (
		<div>
			{props.n1} + {props.n2} = {props.n1 + props.n2}
		</div>
	)
}

If I were to use this like so:

<Add n1={2} n2={3} />

Here's how that would be rendered:

NOTE: Props can be anything. In our example they're numbers, but they can also be (and often are) strings, arrays, objects, functions, etc.

Let's say we want to default the n2 to 0 in the event someone doesn't provide it (like <Add n1={2} />). One limit to props is that you're not allowed to change them. So you couldn't do something like this:

function Add(props) {
	if (typeof props.n2 === 'undefined') {
		props.n2 = 0
	}
	return (
		<div>
			{props.n1} + {props.n2} = {props.n1 + props.n2}
		</div>
	)
}

If we try to do this, we'll get the following error:

TypeError: Cannot add property n2, object is not extensible

This is simple enough to solve though:

function Add(props) {
	let n2 = props.n2
	if (typeof n2 === 'undefined') {
		n2 = 0
	}
	return (
		<div>
			{props.n1} + {n2} = {props.n1 + n2}
		</div>
	)
}

Or, often, you'll find people use destructuring syntax with default values as well (this is my personal preference):

function Add({ n1, n2 = 0 }) {
	return (
		<div>
			{n1} + {n2} = {n1 + n2}
		</div>
	)
}

This is awesome, but what if I want to dynamically change the props value? Let's say I wanted to build something like this:

Without state, here's how I might try to accomplish that:

function AddWithInput(props) {
	function handleInputChange(event) {
		const input = event.target
		const newN2 = Number(input.value)
		props.n2 = newN2
	}
	return (
		<div>
			{props.n1} +{' '}
			<input type="number" value={props.n2} onChange={handleInputChange} /> ={' '}
			{props.n1 + props.n2}
		</div>
	)
}

However, this will not work for two reasons:

  1. React doesn't know that we've updated the n2 value of our props object, so it wont update the DOM when we change props.n2, so we wont see our changes anyway
  2. We'll get the TypeError warning as before

This is where state comes in.

State

State is data that changes over time, and that's perfect for our situation:

function AddWithInput(props) {
	const [n2, setN2] = React.useState(0)

	function handleInputChange(event) {
		const input = event.target
		const newN2 = Number(input.value)
		setN2(newN2)
	}

	return (
		<div>
			{props.n1} +{' '}
			<input type="number" value={n2} onChange={handleInputChange} /> ={' '}
			{props.n1 + n2}
		</div>
	)
}

That will work, and this is precisely what React state is intended to be used for. It's intended to track data values over the lifetime of the component (so long as the component exists on the page).

However, users of the AddWithInput component can no longer set the initial value of n2 anymore. With the way that component is implemented currently, it's not referencing props.n2 at all. But we can make this work by using props when we initialize our state:

function AddWithInput(props) {
	const [n2, setN2] = React.useState(props.n2)

	// ... etc...
}

Now if someone were to do this: <AddWithInput n1={2} n2={3} /> then the result would look like this (notice that the initial input value is 3):

So our props are "arguments" or "inputs" that we can pass to a component, and state is something that is managed within the component and can change over time.

Let me just clean this component up a little bit and I'll explain my changes:

function AddWithInput({ n1, initialN2 = 0 }) {
	const [n2, setN2] = React.useState(initialN2)

	function handleInputChange(event) {
		const input = event.target
		const newN2 = Number(input.value)
		setN2(newN2)
	}

	return (
		<div>
			{n1} + <input type="number" value={n2} onChange={handleInputChange} /> ={' '}
			{n1 + n2}
		</div>
	)
}

I changed to destructuring with defaults for the props, and I changed the prop from n2 to initialN2. When I'm using a prop value to initialize a state value, I typically like to give it the prefix initial to communicate that changes in that prop will not be taken into account. If that's what you want, then you'll want to Lift State Up.

Conclusion

I hope this helps clear up the difference between props and state in React for you. It's a foundational concept. Go ahead and test yourself on this little app below. Where's the state, where are the props?

Error embedding https://codesandbox.io/s/react-codesandbox-oov7o?view=editor

I hope that's helpful! Good luck!