function Component.extend(w,l)if config.typeChecks then assert(Type.of(w)==Type.StatefulComponentClass,"\073\110\118\097\108\105\100 \096\115\101\108\102\096 \097\114\103\117\109\101\110\116 \116\111 \096\101\120\116\101\110\100\096\046")assert(typeof(l)=="\115\116\114\105\110\103","\067\111\109\112\111\110\101\110\116 \099\108\097\115\115 \110\097\109\101 \109\117\115\116 \098\101 \097 \115\116\114\105\110\103")end local U={}for l,w in pairs(w)do if l~="\101\120\116\101\110\100"then U[l]=w end end U[Type]=Type.StatefulComponentClass U.__index=U U.__componentName=l setmetatable(U,componentClassMetatable)return U end function Component.__getDerivedState(U,l,w)if config.internalTypeChecks then internalAssert(Type.of(U)==Type.StatefulComponentInstance,"\073\110\118\097\108\105\100 \117\115\101 \111\102 \096\095\095\103\101\116\068\101\114\105\118\101\100\083\116\097\116\101\096")end local Z=U[InternalData]local A=Z.componentClass if A.getDerivedStateFromProps~=nil then local U=A.getDerivedStateFromProps(l,w)if U~=nil then if config.typeChecks then assert(typeof(U)=="\116\097\098\108\101","\103\101\116\068\101\114\105\118\101\100\083\116\097\116\101\070\114\111\109\080\114\111\112\115 \109\117\115\116 \114\101\116\117\114\110 \097 \116\097\098\108\101\033")end return U end end return nil end function Component.setState(w,l)if config.typeChecks then assert(Type.of(w)==Type.StatefulComponentInstance,"\073\110\118\097\108\105\100 \096\115\101\108\102\096 \097\114\103\117\109\101\110\116 \116\111 \096\101\120\116\101\110\100\096\046")end local U=w[InternalData]local Z=U.lifecyclePhase if Z==ComponentLifecyclePhase.ShouldUpdate or Z==ComponentLifecyclePhase.WillUpdate or Z==ComponentLifecyclePhase.Render or Z==ComponentLifecyclePhase.WillUnmount then local l=invalidSetStateMessages[U.lifecyclePhase]local w=l:format(tostring(U.componentClass))error(w,2)end local A=U.pendingState local N if typeof(l)=="\102\117\110\099\116\105\111\110"then N=l(A or w.state,w.props)if N==nil then return end elseif typeof(l)=="\116\097\098\108\101"then N=l else error("\073\110\118\097\108\105\100 \097\114\103\117\109\101\110\116 \116\111 \115\101\116\083\116\097\116\101\044 \101\120\112\101\099\116\101\100 \102\117\110\099\116\105\111\110 \111\114 \116\097\098\108\101",2)end local o if A~=nil then o=assign(A,N)else o=assign({},w.state,N)end if Z==ComponentLifecyclePhase.Init then local l=w:__getDerivedState(w.props,o)w.state=assign(o,l)elseif Z==ComponentLifecyclePhase.DidMount or Z==ComponentLifecyclePhase.DidUpdate or Z==ComponentLifecyclePhase.ReconcileChildren then local l=w:__getDerivedState(w.props,o)U.pendingState=assign(o,l)elseif Z==ComponentLifecyclePhase.Idle then w:__update(nil,o)else local l=invalidSetStateMessages.default local w=l:format(tostring(U.componentClass))error(w,2)end end
--[[
	A method called by consumers of Roact to create a new component class.
	Components can not be extended beyond this point, with the exception of
	PureComponent.
]]
function Component:extend(name)
	if config.typeChecks then
		assert(Type.of(self) == Type.StatefulComponentClass, "Invalid `self` argument to `extend`.")
		assert(typeof(name) == "string", "Component class name must be a string")
	end

	local class = {}

	for key, value in pairs(self) do
		-- Roact opts to make consumers use composition over inheritance, which
		-- lines up with React.
		-- https://reactjs.org/docs/composition-vs-inheritance.html
		if key ~= "extend" then
			class[key] = value
		end
	end

	class[Type] = Type.StatefulComponentClass
	class.__index = class
	class.__componentName = name

	setmetatable(class, componentClassMetatable)

	return class
end

function Component:__getDerivedState(incomingProps, incomingState)
	if config.internalTypeChecks then
		internalAssert(Type.of(self) == Type.StatefulComponentInstance, "Invalid use of `__getDerivedState`")
	end

	local internalData = self[InternalData]
	local componentClass = internalData.componentClass

	if componentClass.getDerivedStateFromProps ~= nil then
		local derivedState = componentClass.getDerivedStateFromProps(incomingProps, incomingState)

		if derivedState ~= nil then
			if config.typeChecks then
				assert(typeof(derivedState) == "table", "getDerivedStateFromProps must return a table!")
			end

			return derivedState
		end
	end

	return nil
end

function Component:setState(mapState)
	if config.typeChecks then
		assert(Type.of(self) == Type.StatefulComponentInstance, "Invalid `self` argument to `extend`.")
	end

	local internalData = self[InternalData]
	local lifecyclePhase = internalData.lifecyclePhase

	--[[
		When preparing to update, rendering, or unmounting, it is not safe
		to call `setState` as it will interfere with in-flight updates. It's
		also disallowed during unmounting
	]]
	if
		lifecyclePhase == ComponentLifecyclePhase.ShouldUpdate
		or lifecyclePhase == ComponentLifecyclePhase.WillUpdate
		or lifecyclePhase == ComponentLifecyclePhase.Render
		or lifecyclePhase == ComponentLifecyclePhase.WillUnmount
	then
		local messageTemplate = invalidSetStateMessages[internalData.lifecyclePhase]

		local message = messageTemplate:format(tostring(internalData.componentClass))

		error(message, 2)
	end

	local pendingState = internalData.pendingState

	local partialState
	if typeof(mapState) == "function" then
		partialState = mapState(pendingState or self.state, self.props)

		-- Abort the state update if the given state updater function returns nil
		if partialState == nil then
			return
		end
	elseif typeof(mapState) == "table" then
		partialState = mapState
	else
		error("Invalid argument to setState, expected function or table", 2)
	end

	local newState
	if pendingState ~= nil then
		newState = assign(pendingState, partialState)
	else
		newState = assign({}, self.state, partialState)
	end

	if lifecyclePhase == ComponentLifecyclePhase.Init then
		-- If `setState` is called in `init`, we can skip triggering an update!
		local derivedState = self:__getDerivedState(self.props, newState)
		self.state = assign(newState, derivedState)
	elseif
		lifecyclePhase == ComponentLifecyclePhase.DidMount
		or lifecyclePhase == ComponentLifecyclePhase.DidUpdate
		or lifecyclePhase == ComponentLifecyclePhase.ReconcileChildren
	then
		--[[
			During certain phases of the component lifecycle, it's acceptable to
			allow `setState` but defer the update until we're done with ones in flight.
			We do this by collapsing it into any pending updates we have.
		]]
		local derivedState = self:__getDerivedState(self.props, newState)
		internalData.pendingState = assign(newState, derivedState)
	elseif lifecyclePhase == ComponentLifecyclePhase.Idle then
		-- Outside of our lifecycle, the state update is safe to make immediately
		self:__update(nil, newState)
	else
		local messageTemplate = invalidSetStateMessages.default

		local message = messageTemplate:format(tostring(internalData.componentClass))

		error(message, 2)
	end
end
